Giter Club home page Giter Club logo

apidoc's People

Contributors

dhellmann avatar itsmoosh avatar meggycal avatar paulmelnikow avatar stephenfin avatar zaneb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

apidoc's Issues

Support more config options

Thanks for this useful shim!

I'm getting some warnings because there isn't a way to set --no-toc, and I'd also like to be able to set --module-first. It would be great to have a way to provide those options.

Add support for Python 3.12

Currently this project relies on pbr which internally still uses distutils which got removed in Python 3.12. Since pbr is a openstack project, it probably will take a while until it support newer python versions. It is probably a good idea to migrate to a standard pyproject setup in the meantime to support Python 3.12.

Cython modules that use __init__.pyx instead of __init__.py are broken

Cython modules that use __init__.pyx instead of __init__.py are broken and are not picked up properly. (I get a weird entry for the parent folder of the actual module and not the module itself, and that entry is not clickable so it's kind of unbrowseable)

Let me know if this is an upstream bug e.g. in sphinx.ext.autodocor somewhere else, I am a little confused about sphinx's project structure ๐Ÿ˜ฌ

WARNING: Inline literal start-string without end-string.

I am using Sphinx to create HTML documentation for project U-Boot (http://git.denx.de/u-boot.git). The documentation is created via

make htmldocs

The documentation for some functions is rendered incorrectly.

File lib/efi_loader/efi_boottime.c has the following:

/**
 * efi_create_event() - create an event
 * @type:            type of the event to create
 * @notify_tpl:      task priority level of the event
 * @notify_function: notification function of the event
 * @notify_context:  pointer passed to the notification function
 * @group:           event group
 * @event:           created event
 *
 * This function is used inside U-Boot code to create an event.
 *
 * For the API function implementing the CreateEvent service see
 * efi_create_event_ext.
 *
 * Return: status code
 */
efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
                              void (EFIAPI *notify_function) (
                                        struct efi_event *event,
                                        void *context),
                              void *notify_context, efi_guid_t *group,
                              struct efi_event **event)
{

This produces a warning:

./lib/efi_loader/efi_boottime.c:583: WARNING: Inline literal start-string without end-string.
./lib/efi_loader/efi_boottime.c:583: WARNING: Inline emphasis start-string without end-string.
./lib/efi_loader/efi_boottime.c:583: WARNING: Inline emphasis start-string without end-string.
./lib/efi_loader/efi_boottime.c:583: WARNING: Inline emphasis start-string without end-string.

The parameter notfiy_function is rendered as:

``void (EFIAPI *notify_function) ( struct efi_event *event, void *context) ``
    undescribed

Why is the warning thrown?
Why is the parameter description missing?
Why do I get the superfluous ``?

Best regards

Heinrich Schuchardt

Passing multiple apidoc_module_dir's

We have a centralized doc generation where sphinx-apidoc is called on each repo and the generated rst files are used to generate the documentation,

Given this is a pre-stage operation done outside sphinx, current extension seemed like a good way to avoid the pre-stage creation of rst.
Only caveat here is that apidoc_module_dir only accepts a single path. Can this be enhanced to accept a list of paths?

warnings created from derived classes when constructor has no docstring

We recently ran into a subtle but reproducible problem generating api docs for some of our projects. The problem case is as follows.

  1. Create a base class with a constructor, and provide both a class doc string and a constructor doc string, something like this:
class MyBase:
    """Base class docstring"""

    def __init__(self, fubar):
        """
        Args:
            fubar (str):
                parameter description here
        """
  1. Create a derived class that has an overloaded constructor, with no doc string, something like this:
class MyDerived(MyBase):
    def __init__(self):
        pass
  1. Enable the auto content option in Sphinx to combine the class doc string and constructor doc strings together (ie: autoclass_content = "both")

  2. Attempt to generate the docs using the apidoc extension.
    Expected behavior: the API docs for both the base and derived classes should be generated without warnings.
    Actual behavior: docs for the base class generate correctly, but docs for the derived class produce the following warning
    "docstring of sample.MyDerived: WARNING: Unexpected indentation."

This is a rather insidious warning because it points the developer to the derived class as the root cause of the problem, but there is no obvious correlation between the code of the derived class and the actual cause of the problem. This is further exacerbated when the derived class is in a different project or library from the base class, because then the developer needs to review the contents of the full inheritance stack. However, even after reviewing the code for the base class (which may or may not be the direct parent class of the one exposing the error) there is no obvious correlation between the warning and the code because the doc strings on the base class(es) are defined and correctly formatted, and Sphinx/apidoc do not complain when generating the docs for the base class.

After much ad-hoc testing I was able to deduce that simply adding a doc string to the constructor on the derived class was sufficient to circumvent the error, but when working on a large number of Python projects and sharing those projects across many developers, problems like this are hard to avoid in practice.

My team manages dozens of Python projects, and are trying to build docs for all without having any warnings produced, so we've opted to disable the combined auto content flag to avoid these superfluous warnings. However, this is just a hack/workaround to get us by for now. I hope someone can investigate the root cause of this problem and fix it so that docs for derived classes can be generated without warnings.

Is it possible to run example code to generate an image?

Hello,
Foremost, thanks a lot for this great extension! I was wondering if there is a way to execute example blocks in the docstrings. For example, I have one routine, which modifies input data in a certain way and the result is best seen in form of a plot. I would like to have an example as part of my docstring, e.g.

def myplotting_routine()
    """My docstring

    Example
    ------------
    >>> myplotting_routine()
    """

and have the generated plot attached in the rendered documentation.
Is this possible with apidoc?

0.3.0: test suite fails

+ py.test
========================================================================================= test session starts ==========================================================================================
platform linux -- Python 3.8.3, pytest-4.6.9, py-1.8.0, pluggy-0.13.1
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/home/tkloczko/rpmbuild/BUILD/sphinxcontrib-apidoc-0.3.0/.hypothesis/examples')
rootdir: /home/tkloczko/rpmbuild/BUILD/sphinxcontrib-apidoc-0.3.0
plugins: forked-1.1.1, mock-1.10.4, expect-1.1.0, hypothesis-4.23.8, xdist-1.31.0, httpbin-0.3.0, cov-2.8.1, timeout-1.3.4, rerunfailures-8.0, flaky-3.6.1
collected 5 items

tests/test_ext.py EEEEE                                                                                                                                                                          [100%]

================================================================================================ ERRORS ================================================================================================
____________________________________________________________________________________ ERROR at setup of test_basics _____________________________________________________________________________________

self = <sphinx.registry.SphinxComponentRegistry object at 0x7f859000a8b0>, app = <[AttributeError("'NoneType' object has no attribute 'name'") raised in repr()] SphinxTestApp object at 0x7f8590006070>
extname = 'sphinxcontrib.apidoc'

    def load_extension(self, app, extname):
        # type: (Sphinx, str) -> None
        """Load a Sphinx extension."""
        if extname in app.extensions:  # alread loaded
            return
        if extname in EXTENSION_BLACKLIST:
            logger.warning(__('the extension %r was already merged with Sphinx since '
                              'version %s; this extension is ignored.'),
                           extname, EXTENSION_BLACKLIST[extname])
            return

        # update loading context
        prefix = __('while setting up extension %s:') % extname
        with prefixed_warnings(prefix):
            try:
>               mod = import_module(extname)

/usr/lib/python3.8/site-packages/sphinx/registry.py:475:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', package = None

    def import_module(name, package=None):
        """Import a module.

        The 'package' argument is required when performing a relative import. It
        specifies the package to use as the anchor point from which to resolve the
        relative import to an absolute import.

        """
        level = 0
        if name.startswith('.'):
            if not package:
                msg = ("the 'package' argument is required to perform a relative "
                       "import for {!r}")
                raise TypeError(msg.format(name))
            for character in name:
                if character != '.':
                    break
                level += 1
>       return _bootstrap._gcd_import(name[level:], package, level)

/usr/lib64/python3.8/importlib/__init__.py:127:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', package = None, level = 0

>   ???

<frozen importlib._bootstrap>:1014:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', import_ = <function _gcd_import at 0x7f860c3c04c0>

>   ???

<frozen importlib._bootstrap>:991:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', import_ = <function _gcd_import at 0x7f860c3c04c0>

>   ???
E   ModuleNotFoundError: No module named 'sphinxcontrib.apidoc'

<frozen importlib._bootstrap>:973: ModuleNotFoundError

During handling of the above exception, another exception occurred:

test_params = {'shared_result': None}, app_params = app_params(args=['html'], kwargs={'srcdir': path('/tmp/apidoc-yxbzqtx6/basics')}), make_app = <function make_app.<locals>.make at 0x7f858ffcd700>
shared_result = <sphinx.testing.fixtures.SharedResult object at 0x7f858fe5d6d0>

    @pytest.fixture(scope='function')
    def app(test_params, app_params, make_app, shared_result):
        """
        provides sphinx.application.Sphinx object
        """
        args, kwargs = app_params
>       app_ = make_app(*args, **kwargs)

/usr/lib/python3.8/site-packages/sphinx/testing/fixtures.py:110:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.8/site-packages/sphinx/testing/fixtures.py:156: in make
    app_ = util.SphinxTestApp(*args, **kwargs)  # type: Any
/usr/lib/python3.8/site-packages/sphinx/testing/util.py:130: in __init__
    super().__init__(srcdir, confdir, outdir, doctreedir,
/usr/lib/python3.8/site-packages/sphinx/application.py:243: in __init__
    self.setup_extension(extension)
/usr/lib/python3.8/site-packages/sphinx/application.py:402: in setup_extension
    self.registry.load_extension(self, extname)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <sphinx.registry.SphinxComponentRegistry object at 0x7f859000a8b0>, app = <[AttributeError("'NoneType' object has no attribute 'name'") raised in repr()] SphinxTestApp object at 0x7f8590006070>
extname = 'sphinxcontrib.apidoc'

    def load_extension(self, app, extname):
        # type: (Sphinx, str) -> None
        """Load a Sphinx extension."""
        if extname in app.extensions:  # alread loaded
            return
        if extname in EXTENSION_BLACKLIST:
            logger.warning(__('the extension %r was already merged with Sphinx since '
                              'version %s; this extension is ignored.'),
                           extname, EXTENSION_BLACKLIST[extname])
            return

        # update loading context
        prefix = __('while setting up extension %s:') % extname
        with prefixed_warnings(prefix):
            try:
                mod = import_module(extname)
            except ImportError as err:
                logger.verbose(__('Original exception:\n') + traceback.format_exc())
>               raise ExtensionError(__('Could not import extension %s') % extname, err)
E               sphinx.errors.ExtensionError: Could not import extension sphinxcontrib.apidoc (exception: No module named 'sphinxcontrib.apidoc')

/usr/lib/python3.8/site-packages/sphinx/registry.py:478: ExtensionError
___________________________________________________________________________________ ERROR at setup of test_advanced ____________________________________________________________________________________

self = <sphinx.registry.SphinxComponentRegistry object at 0x7f858fa0d370>, app = <[AttributeError("'NoneType' object has no attribute 'name'") raised in repr()] SphinxTestApp object at 0x7f858fa0daf0>
extname = 'sphinxcontrib.apidoc'

    def load_extension(self, app, extname):
        # type: (Sphinx, str) -> None
        """Load a Sphinx extension."""
        if extname in app.extensions:  # alread loaded
            return
        if extname in EXTENSION_BLACKLIST:
            logger.warning(__('the extension %r was already merged with Sphinx since '
                              'version %s; this extension is ignored.'),
                           extname, EXTENSION_BLACKLIST[extname])
            return

        # update loading context
        prefix = __('while setting up extension %s:') % extname
        with prefixed_warnings(prefix):
            try:
>               mod = import_module(extname)

/usr/lib/python3.8/site-packages/sphinx/registry.py:475:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', package = None

    def import_module(name, package=None):
        """Import a module.

        The 'package' argument is required when performing a relative import. It
        specifies the package to use as the anchor point from which to resolve the
        relative import to an absolute import.

        """
        level = 0
        if name.startswith('.'):
            if not package:
                msg = ("the 'package' argument is required to perform a relative "
                       "import for {!r}")
                raise TypeError(msg.format(name))
            for character in name:
                if character != '.':
                    break
                level += 1
>       return _bootstrap._gcd_import(name[level:], package, level)

/usr/lib64/python3.8/importlib/__init__.py:127:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', package = None, level = 0

>   ???

<frozen importlib._bootstrap>:1014:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', import_ = <function _gcd_import at 0x7f860c3c04c0>

>   ???

<frozen importlib._bootstrap>:991:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', import_ = <function _gcd_import at 0x7f860c3c04c0>

>   ???
E   ModuleNotFoundError: No module named 'sphinxcontrib.apidoc'

<frozen importlib._bootstrap>:973: ModuleNotFoundError

During handling of the above exception, another exception occurred:

test_params = {'shared_result': None}, app_params = app_params(args=['html'], kwargs={'srcdir': path('/tmp/apidoc-yxbzqtx6/advanced')}), make_app = <function make_app.<locals>.make at 0x7f858faaf9d0>
shared_result = <sphinx.testing.fixtures.SharedResult object at 0x7f858fa0db50>

    @pytest.fixture(scope='function')
    def app(test_params, app_params, make_app, shared_result):
        """
        provides sphinx.application.Sphinx object
        """
        args, kwargs = app_params
>       app_ = make_app(*args, **kwargs)

/usr/lib/python3.8/site-packages/sphinx/testing/fixtures.py:110:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.8/site-packages/sphinx/testing/fixtures.py:156: in make
    app_ = util.SphinxTestApp(*args, **kwargs)  # type: Any
/usr/lib/python3.8/site-packages/sphinx/testing/util.py:130: in __init__
    super().__init__(srcdir, confdir, outdir, doctreedir,
/usr/lib/python3.8/site-packages/sphinx/application.py:243: in __init__
    self.setup_extension(extension)
/usr/lib/python3.8/site-packages/sphinx/application.py:402: in setup_extension
    self.registry.load_extension(self, extname)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <sphinx.registry.SphinxComponentRegistry object at 0x7f858fa0d370>, app = <[AttributeError("'NoneType' object has no attribute 'name'") raised in repr()] SphinxTestApp object at 0x7f858fa0daf0>
extname = 'sphinxcontrib.apidoc'

    def load_extension(self, app, extname):
        # type: (Sphinx, str) -> None
        """Load a Sphinx extension."""
        if extname in app.extensions:  # alread loaded
            return
        if extname in EXTENSION_BLACKLIST:
            logger.warning(__('the extension %r was already merged with Sphinx since '
                              'version %s; this extension is ignored.'),
                           extname, EXTENSION_BLACKLIST[extname])
            return

        # update loading context
        prefix = __('while setting up extension %s:') % extname
        with prefixed_warnings(prefix):
            try:
                mod = import_module(extname)
            except ImportError as err:
                logger.verbose(__('Original exception:\n') + traceback.format_exc())
>               raise ExtensionError(__('Could not import extension %s') % extname, err)
E               sphinx.errors.ExtensionError: Could not import extension sphinxcontrib.apidoc (exception: No module named 'sphinxcontrib.apidoc')

/usr/lib/python3.8/site-packages/sphinx/registry.py:478: ExtensionError
_______________________________________________________________________________ ERROR at setup of test_advanced_negative _______________________________________________________________________________

self = <sphinx.registry.SphinxComponentRegistry object at 0x7f858f9aeee0>, app = <[AttributeError("'NoneType' object has no attribute 'name'") raised in repr()] SphinxTestApp object at 0x7f858f9aea30>
extname = 'sphinxcontrib.apidoc'

    def load_extension(self, app, extname):
        # type: (Sphinx, str) -> None
        """Load a Sphinx extension."""
        if extname in app.extensions:  # alread loaded
            return
        if extname in EXTENSION_BLACKLIST:
            logger.warning(__('the extension %r was already merged with Sphinx since '
                              'version %s; this extension is ignored.'),
                           extname, EXTENSION_BLACKLIST[extname])
            return

        # update loading context
        prefix = __('while setting up extension %s:') % extname
        with prefixed_warnings(prefix):
            try:
>               mod = import_module(extname)

/usr/lib/python3.8/site-packages/sphinx/registry.py:475:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', package = None

    def import_module(name, package=None):
        """Import a module.

        The 'package' argument is required when performing a relative import. It
        specifies the package to use as the anchor point from which to resolve the
        relative import to an absolute import.

        """
        level = 0
        if name.startswith('.'):
            if not package:
                msg = ("the 'package' argument is required to perform a relative "
                       "import for {!r}")
                raise TypeError(msg.format(name))
            for character in name:
                if character != '.':
                    break
                level += 1
>       return _bootstrap._gcd_import(name[level:], package, level)

/usr/lib64/python3.8/importlib/__init__.py:127:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', package = None, level = 0

>   ???

<frozen importlib._bootstrap>:1014:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', import_ = <function _gcd_import at 0x7f860c3c04c0>

>   ???

<frozen importlib._bootstrap>:991:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', import_ = <function _gcd_import at 0x7f860c3c04c0>

>   ???
E   ModuleNotFoundError: No module named 'sphinxcontrib.apidoc'

<frozen importlib._bootstrap>:973: ModuleNotFoundError

During handling of the above exception, another exception occurred:

test_params = {'shared_result': None}, app_params = app_params(args=['html'], kwargs={'srcdir': path('/tmp/apidoc-yxbzqtx6/advanced-negative')})
make_app = <function make_app.<locals>.make at 0x7f858faff670>, shared_result = <sphinx.testing.fixtures.SharedResult object at 0x7f858f9aeac0>

    @pytest.fixture(scope='function')
    def app(test_params, app_params, make_app, shared_result):
        """
        provides sphinx.application.Sphinx object
        """
        args, kwargs = app_params
>       app_ = make_app(*args, **kwargs)

/usr/lib/python3.8/site-packages/sphinx/testing/fixtures.py:110:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.8/site-packages/sphinx/testing/fixtures.py:156: in make
    app_ = util.SphinxTestApp(*args, **kwargs)  # type: Any
/usr/lib/python3.8/site-packages/sphinx/testing/util.py:130: in __init__
    super().__init__(srcdir, confdir, outdir, doctreedir,
/usr/lib/python3.8/site-packages/sphinx/application.py:243: in __init__
    self.setup_extension(extension)
/usr/lib/python3.8/site-packages/sphinx/application.py:402: in setup_extension
    self.registry.load_extension(self, extname)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <sphinx.registry.SphinxComponentRegistry object at 0x7f858f9aeee0>, app = <[AttributeError("'NoneType' object has no attribute 'name'") raised in repr()] SphinxTestApp object at 0x7f858f9aea30>
extname = 'sphinxcontrib.apidoc'

    def load_extension(self, app, extname):
        # type: (Sphinx, str) -> None
        """Load a Sphinx extension."""
        if extname in app.extensions:  # alread loaded
            return
        if extname in EXTENSION_BLACKLIST:
            logger.warning(__('the extension %r was already merged with Sphinx since '
                              'version %s; this extension is ignored.'),
                           extname, EXTENSION_BLACKLIST[extname])
            return

        # update loading context
        prefix = __('while setting up extension %s:') % extname
        with prefixed_warnings(prefix):
            try:
                mod = import_module(extname)
            except ImportError as err:
                logger.verbose(__('Original exception:\n') + traceback.format_exc())
>               raise ExtensionError(__('Could not import extension %s') % extname, err)
E               sphinx.errors.ExtensionError: Could not import extension sphinxcontrib.apidoc (exception: No module named 'sphinxcontrib.apidoc')

/usr/lib/python3.8/site-packages/sphinx/registry.py:478: ExtensionError
_____________________________________________________________________________ ERROR at setup of test_missing_configuration _____________________________________________________________________________

self = <sphinx.registry.SphinxComponentRegistry object at 0x7f858f99b0a0>, app = <[AttributeError("'NoneType' object has no attribute 'name'") raised in repr()] SphinxTestApp object at 0x7f858f99bbe0>
extname = 'sphinxcontrib.apidoc'

    def load_extension(self, app, extname):
        # type: (Sphinx, str) -> None
        """Load a Sphinx extension."""
        if extname in app.extensions:  # alread loaded
            return
        if extname in EXTENSION_BLACKLIST:
            logger.warning(__('the extension %r was already merged with Sphinx since '
                              'version %s; this extension is ignored.'),
                           extname, EXTENSION_BLACKLIST[extname])
            return

        # update loading context
        prefix = __('while setting up extension %s:') % extname
        with prefixed_warnings(prefix):
            try:
>               mod = import_module(extname)

/usr/lib/python3.8/site-packages/sphinx/registry.py:475:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', package = None

    def import_module(name, package=None):
        """Import a module.

        The 'package' argument is required when performing a relative import. It
        specifies the package to use as the anchor point from which to resolve the
        relative import to an absolute import.

        """
        level = 0
        if name.startswith('.'):
            if not package:
                msg = ("the 'package' argument is required to perform a relative "
                       "import for {!r}")
                raise TypeError(msg.format(name))
            for character in name:
                if character != '.':
                    break
                level += 1
>       return _bootstrap._gcd_import(name[level:], package, level)

/usr/lib64/python3.8/importlib/__init__.py:127:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', package = None, level = 0

>   ???

<frozen importlib._bootstrap>:1014:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', import_ = <function _gcd_import at 0x7f860c3c04c0>

>   ???

<frozen importlib._bootstrap>:991:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', import_ = <function _gcd_import at 0x7f860c3c04c0>

>   ???
E   ModuleNotFoundError: No module named 'sphinxcontrib.apidoc'

<frozen importlib._bootstrap>:973: ModuleNotFoundError

During handling of the above exception, another exception occurred:

test_params = {'shared_result': None}, app_params = app_params(args=['html'], kwargs={'srcdir': path('/tmp/apidoc-yxbzqtx6/missing-configuration')})
make_app = <function make_app.<locals>.make at 0x7f858f9fbdc0>, shared_result = <sphinx.testing.fixtures.SharedResult object at 0x7f858f99be50>

    @pytest.fixture(scope='function')
    def app(test_params, app_params, make_app, shared_result):
        """
        provides sphinx.application.Sphinx object
        """
        args, kwargs = app_params
>       app_ = make_app(*args, **kwargs)

/usr/lib/python3.8/site-packages/sphinx/testing/fixtures.py:110:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.8/site-packages/sphinx/testing/fixtures.py:156: in make
    app_ = util.SphinxTestApp(*args, **kwargs)  # type: Any
/usr/lib/python3.8/site-packages/sphinx/testing/util.py:130: in __init__
    super().__init__(srcdir, confdir, outdir, doctreedir,
/usr/lib/python3.8/site-packages/sphinx/application.py:243: in __init__
    self.setup_extension(extension)
/usr/lib/python3.8/site-packages/sphinx/application.py:402: in setup_extension
    self.registry.load_extension(self, extname)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <sphinx.registry.SphinxComponentRegistry object at 0x7f858f99b0a0>, app = <[AttributeError("'NoneType' object has no attribute 'name'") raised in repr()] SphinxTestApp object at 0x7f858f99bbe0>
extname = 'sphinxcontrib.apidoc'

    def load_extension(self, app, extname):
        # type: (Sphinx, str) -> None
        """Load a Sphinx extension."""
        if extname in app.extensions:  # alread loaded
            return
        if extname in EXTENSION_BLACKLIST:
            logger.warning(__('the extension %r was already merged with Sphinx since '
                              'version %s; this extension is ignored.'),
                           extname, EXTENSION_BLACKLIST[extname])
            return

        # update loading context
        prefix = __('while setting up extension %s:') % extname
        with prefixed_warnings(prefix):
            try:
                mod = import_module(extname)
            except ImportError as err:
                logger.verbose(__('Original exception:\n') + traceback.format_exc())
>               raise ExtensionError(__('Could not import extension %s') % extname, err)
E               sphinx.errors.ExtensionError: Could not import extension sphinxcontrib.apidoc (exception: No module named 'sphinxcontrib.apidoc')

/usr/lib/python3.8/site-packages/sphinx/registry.py:478: ExtensionError
_______________________________________________________________________________ ERROR at setup of test_invalid_directory _______________________________________________________________________________

self = <sphinx.registry.SphinxComponentRegistry object at 0x7f858fa17130>, app = <[AttributeError("'NoneType' object has no attribute 'name'") raised in repr()] SphinxTestApp object at 0x7f858fa17ca0>
extname = 'sphinxcontrib.apidoc'

    def load_extension(self, app, extname):
        # type: (Sphinx, str) -> None
        """Load a Sphinx extension."""
        if extname in app.extensions:  # alread loaded
            return
        if extname in EXTENSION_BLACKLIST:
            logger.warning(__('the extension %r was already merged with Sphinx since '
                              'version %s; this extension is ignored.'),
                           extname, EXTENSION_BLACKLIST[extname])
            return

        # update loading context
        prefix = __('while setting up extension %s:') % extname
        with prefixed_warnings(prefix):
            try:
>               mod = import_module(extname)

/usr/lib/python3.8/site-packages/sphinx/registry.py:475:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', package = None

    def import_module(name, package=None):
        """Import a module.

        The 'package' argument is required when performing a relative import. It
        specifies the package to use as the anchor point from which to resolve the
        relative import to an absolute import.

        """
        level = 0
        if name.startswith('.'):
            if not package:
                msg = ("the 'package' argument is required to perform a relative "
                       "import for {!r}")
                raise TypeError(msg.format(name))
            for character in name:
                if character != '.':
                    break
                level += 1
>       return _bootstrap._gcd_import(name[level:], package, level)

/usr/lib64/python3.8/importlib/__init__.py:127:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', package = None, level = 0

>   ???

<frozen importlib._bootstrap>:1014:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', import_ = <function _gcd_import at 0x7f860c3c04c0>

>   ???

<frozen importlib._bootstrap>:991:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

name = 'sphinxcontrib.apidoc', import_ = <function _gcd_import at 0x7f860c3c04c0>

>   ???
E   ModuleNotFoundError: No module named 'sphinxcontrib.apidoc'

<frozen importlib._bootstrap>:973: ModuleNotFoundError

During handling of the above exception, another exception occurred:

test_params = {'shared_result': None}, app_params = app_params(args=['html'], kwargs={'srcdir': path('/tmp/apidoc-yxbzqtx6/invalid-directory')})
make_app = <function make_app.<locals>.make at 0x7f858fa05820>, shared_result = <sphinx.testing.fixtures.SharedResult object at 0x7f858fa17d00>

    @pytest.fixture(scope='function')
    def app(test_params, app_params, make_app, shared_result):
        """
        provides sphinx.application.Sphinx object
        """
        args, kwargs = app_params
>       app_ = make_app(*args, **kwargs)

/usr/lib/python3.8/site-packages/sphinx/testing/fixtures.py:110:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.8/site-packages/sphinx/testing/fixtures.py:156: in make
    app_ = util.SphinxTestApp(*args, **kwargs)  # type: Any
/usr/lib/python3.8/site-packages/sphinx/testing/util.py:130: in __init__
    super().__init__(srcdir, confdir, outdir, doctreedir,
/usr/lib/python3.8/site-packages/sphinx/application.py:243: in __init__
    self.setup_extension(extension)
/usr/lib/python3.8/site-packages/sphinx/application.py:402: in setup_extension
    self.registry.load_extension(self, extname)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <sphinx.registry.SphinxComponentRegistry object at 0x7f858fa17130>, app = <[AttributeError("'NoneType' object has no attribute 'name'") raised in repr()] SphinxTestApp object at 0x7f858fa17ca0>
extname = 'sphinxcontrib.apidoc'

    def load_extension(self, app, extname):
        # type: (Sphinx, str) -> None
        """Load a Sphinx extension."""
        if extname in app.extensions:  # alread loaded
            return
        if extname in EXTENSION_BLACKLIST:
            logger.warning(__('the extension %r was already merged with Sphinx since '
                              'version %s; this extension is ignored.'),
                           extname, EXTENSION_BLACKLIST[extname])
            return

        # update loading context
        prefix = __('while setting up extension %s:') % extname
        with prefixed_warnings(prefix):
            try:
                mod = import_module(extname)
            except ImportError as err:
                logger.verbose(__('Original exception:\n') + traceback.format_exc())
>               raise ExtensionError(__('Could not import extension %s') % extname, err)
E               sphinx.errors.ExtensionError: Could not import extension sphinxcontrib.apidoc (exception: No module named 'sphinxcontrib.apidoc')

/usr/lib/python3.8/site-packages/sphinx/registry.py:478: ExtensionError
=========================================================================================== warnings summary ===========================================================================================
/usr/lib/python3.8/site-packages/_pytest/mark/structures.py:331
  /usr/lib/python3.8/site-packages/_pytest/mark/structures.py:331: PytestUnknownMarkWarning: Unknown pytest.mark.sphinx - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/latest/mark.html
    warnings.warn(

-- Docs: https://docs.pytest.org/en/latest/warnings.html
================================================================================= 1 warnings, 5 error in 0.66 seconds ==================================================================================

Call to `pbr.version.VersionInfo` raises exception on import

I'm using this extension in Docker on a PaaS provider, Zeit Now, where I'm running documentation builds in response to pull requests.

I'm getting this exception when Sphinx starts up:

# Sphinx version: 1.8.1
# Python version: 2.7.15 (CPython)
# Docutils version: 0.14 
  File "/usr/local/lib/python2.7/site-packages/sphinx/registry.py", line 472, in load_extension
    mod = __import__(extname, None, None, ['setup'])
  File "/usr/local/lib/python2.7/site-packages/sphinxcontrib/apidoc/__init__.py", line 15, in <module>
    __version__ = pbr.version.VersionInfo('apidoc').version_string()
  File "/usr/local/lib/python2.7/site-packages/pbr/version.py", line 467, in version_string
    return self.semantic_version().brief_string()
  File "/usr/local/lib/python2.7/site-packages/pbr/version.py", line 462, in semantic_version
    self._semantic = self._get_version_from_pkg_resources()
  File "/usr/local/lib/python2.7/site-packages/pbr/version.py", line 449, in _get_version_from_pkg_resources
    result_string = packaging.get_version(self.package)
  File "/usr/local/lib/python2.7/site-packages/pbr/packaging.py", line 839, in get_version
    name=package_name))
Exception: Versioning for this project requires either an sdist tarball, or access to an upstream git repository. It's also possible that there is a mismatch between the package name in setup.cfg and the argument given to pbr.version.VersionInfo. Project name apidoc was given, but was not able to be found.

This line seems to be causing it:

https://github.com/sphinx-contrib/apidoc/blob/master/sphinxcontrib/apidoc/__init__.py#L15

The docker image is based on the official Python docker image. It doesn't do anything fancy, just running apt-get install and pip install and cleaning the cache. (I tried disabling the cache clean; no dice.)

Turning off the extension makes the problem go away.

I can't reproduce it locally, even in docker. Here's the Zeit build: https://zeit.co/lace/entente/jcdveazgph/logs

The last thing I tried was reinstalling sphinxcontrib-apidoc while the container was running. That didn't work either.

I'd really appreciate any ideas you might have!

Output of pip freeze:
alabaster==0.7.11
Babel==2.6.0
backports.functools-lru-cache==1.5
baiji==2.10.0
baiji-serialization==2.1.0
boto==2.49.0
cached-property==1.5.1
certifi==2018.8.24
chardet==3.0.4
Click==7.0
coloredlogs==10.0
CommonMark==0.5.4
cycler==0.10.0
docutils==0.14
env-flag==1.0.1
fasteners==0.14.1
futures==3.2.0
harrison==1.1.1
humanfriendly==4.16.1
idna==2.7
imagesize==1.1.0
Jinja2==2.10
kiwisolver==1.0.1
lxml==4.2.5
MarkupSafe==1.0
matplotlib==2.2.3
metabaiji-pod==1.0.7.post1
metablmath==1.2.5.post2
metabochumpy==0.67.6.post2
metabolace==1.1.8.dev1
metabolexecutor==20.0.post1
monotonic==1.5
nose2==0.5.0
numpy==1.15.2
packaging==18.0
pbr==4.2.0
plumbum==1.6.7
progressbar==2.5
property-manager==2.3.1
py-windows-exe==1.0.0
Pygments==2.2.0

setuptools version:

setuptools 40.2.0 from /usr/local/lib/python2.7/site-packages (Python 2.7)

validate function/method params against docstrings

hi, we are using sphinx-apidoc to generate docs

sphinx-apidoc --output-dir docs/kw --no-toc kw && make --directory=docs html

but devs often forget to update docstrings after changing methods/functions. Is there a tool that is able to validate this? I saw stackoverflow question, but no answer there.

Maybe out of scope, but we are at least checking for warnings/errors from sphinx with this CI step:

docs-valid:
  stage: test
  image: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA-py3
  cache:
    key: ${CI_PROJECT_PATH_SLUG}-sphinx
    paths:
      - .doctree/
  script:
    - >
      sphinx-apidoc --output-dir docs/kw --no-toc kw
      && BOOKING_LOGGING_STD_DISABLED=1
      OUTPUT=$(sphinx-build -M html docs docs/_build -q 2>&1 -d .doctree -j 8) || (echo "$OUTPUT"; exit 1);
      echo "$OUTPUT" | grep -E ':[0-9]+: (WARNING|ERROR|SEVERE):' || exit 0;
      echo 'Invalid docstring syntax. Check syntax here -> http://rst.ninjs.org'
      && exit 1

Would be cool if there would be single flag on sphinx-build that would fail on errors/warnings.

Support templating

Hello

Is it possible to add an option to change the default menu item names:

  • the first level has the name of the module while I'd like to have something like "API Reference". Could be an option such as apidoc_title = "API Reference"
  • is it possible to display the content of a module before its sub-modules?
  • using a lot git submodules, seeing "Submodules" in the menu is weird. Is it possible to simply skip this level and gather all sub-module inside the package?

So instead of:

mypackage_name
    mypackage_name package
        Submodules
            mypackage_name.one_module module
            mypackage_name.another_module module
            mypackage_name.yet_another_one module
        Module contents

We would have something like:

API Reference
    mypackage_name package
        Module contents
        mypackage_name.one_module module
        mypackage_name.another_module module
        mypackage_name.yet_another_one module

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.