Sphinx: Sphinx throws an "unexpected indentation" error for abstract methods

Created on 27 Jul 2020  路  7Comments  路  Source: sphinx-doc/sphinx

Describe the bug
It seems sphinx is not properly detecting abstract private methods and is falsely reported an "undexpected indenation" docstring error.

.. automodule:: nbapy.game
   :members:
   :private-members: _endpoint
   :undoc-members:
   :show-inheritance:
# game.py

class _BoxScore(ABC):
    @property
    @classmethod
    @abstractmethod
    def _endpoint(cls):
        return NotImplementedError

# ... # 

class BoxScore(_BoxScore):
    _endpoint = "boxscoretraditionalv2"

$ sphinx-build -n -W -q -b html docs docs/_build/html

Warning, treated as error:
/home/jacob/src/nbapy/nbapy/game.py:docstring of nbapy.game._BoxScore._endpoint:12:Unexpected indentation.
````

I'd like to document _endpoint in all the classes that inherit _BoxScore


**To Reproduce**
Steps to reproduce the behavior:

$ git clone https://github.com/jtpavlock/nbapy
$ cd nbapy
$ poetry install
$ sphinx-build -n -W -q -b html docs docs/_build/html


**Expected behavior**
Sphinx to not throw this warning

**Your project**
[nbapy](https://github.com/jtpavlock/nbapy)

**Environment info**
- OS: Ubuntu 20.04
- Python version: 3.8.2
- Sphinx version: sphinx-build 3.1.2
- Sphinx extensions:  

extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.napoleon",
"sphinx_rtd_theme",
]
```

  • Extra tools: none
autodoc bug

All 7 comments

How _BoxScore._endpoint works? I've never seen a property-classmethod.

Note: Internally, autodoc generates the following reST document for your class. It seems autodoc considers the docstring of classmethod class is a docstring of _BoxScore._endpoint. And it is invalid reST...

.. py:class:: _BoxScore()
   :module: example

   Bases: :class:`abc.ABC`


   .. py:attribute:: _BoxScore._abc_impl
      :module: example
      :value: <_abc_data object>


   .. py:method:: _BoxScore._endpoint
      :module: example
      :abstractmethod:
      :property:

      classmethod(function) -> method

      Convert a function to be a class method.

      A class method receives the class as implicit first argument,
      just like an instance method receives the instance.
      To declare a class method, use this idiom:

        class C:
            @classmethod
            def f(cls, arg1, arg2, ...):
                ...

      It can be called either on the class (e.g. C.f()) or on an instance
      (e.g. C().f()).  The instance is ignored except for its class.
      If a class method is called for a derived class, the derived class
      object is passed as the implied first argument.

      Class methods are different than C++ or Java static methods.
      If you want those, see the staticmethod builtin.

I removed @classmethod and things seem to work fine now, so thanks for picking that out. However, I'm not sure if this is relevant, but I only wish to have _endpoint show up in my documentation, and it seems to be showing all private members.

Does :private-members: _endpoint not do what I expect?

Unfortunately, :private-members: option is a kind of flag-option. It does not take arguments.
https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html

Thanks for the help, I had seen the docs, but wasn't sure if it behaved like :members: or not.

So is there no way to currently do what I am asking without explicitly listing each class and using :autoattribute:?

Yes, there is no way to do that at present. But, I think it is reasonable to support it. Could you file another issue please? Then I'll work on it.

Done https://github.com/sphinx-doc/sphinx/issues/8034! Thanks again for the help.

Thanks,

BTW, I think this issue was already resolved. Can I close this?

Was this page helpful?
0 / 5 - 0 ratings