sphinx-doc / sphinx

The Sphinx documentation generator
https://www.sphinx-doc.org/
Other
6.56k stars 2.12k forks source link

Autodoc fails with "ValueError: wrapper loop when unwrapping..." #7422

Closed lpsinger closed 4 years ago

lpsinger commented 4 years ago

Describe the bug The documentation set for my project fails with error messages like ValueError: wrapper loop when unwrapping ligo.skymap.io.events. The build worked with Sphinx 3.0.0b1, but broke with Sphinx 3.0.0. Just a guess, but I think that #7222 broke it.

To Reproduce Steps to reproduce the behavior:

$ docker run --rm -it python bash
root@da57b757740e:/# git clone https://git.ligo.org/emfollow/gwcelery
Cloning into 'gwcelery'...
warning: redirecting to https://git.ligo.org/emfollow/gwcelery.git/
remote: Enumerating objects: 1558, done.
remote: Counting objects: 100% (1558/1558), done.
remote: Compressing objects: 100% (387/387), done.
remote: Total 13274 (delta 1264), reused 1422 (delta 1163), pack-reused 11716
Receiving objects: 100% (13274/13274), 15.43 MiB | 780.00 KiB/s, done.
Resolving deltas: 100% (9771/9771), done.
root@da57b757740e:/# cd gwcelery
root@da57b757740e:/gwcelery# pip install -r docs-requirements.txt 
Collecting celery[redis]==4.4.0
  Downloading celery-4.4.0-py2.py3-none-any.whl (421 kB)
     |████████████████████████████████| 421 kB 591 kB/s 
Collecting matplotlib
  Downloading matplotlib-3.2.1-cp38-cp38-manylinux1_x86_64.whl (12.4 MB)
     |████████████████████████████████| 12.4 MB 948 kB/s 
Collecting seaborn
  Downloading seaborn-0.10.0-py3-none-any.whl (215 kB)
     |████████████████████████████████| 215 kB 878 kB/s 
Collecting sphinx>=1.8.0b1
  Downloading Sphinx-3.0.0-py3-none-any.whl (2.8 MB)
     |████████████████████████████████| 2.8 MB 1.3 MB/s 
Collecting billiard<4.0,>=3.6.1
  Downloading billiard-3.6.3.0-py3-none-any.whl (89 kB)
     |████████████████████████████████| 89 kB 222 kB/s 
Collecting kombu<4.7,>=4.6.7
  Downloading kombu-4.6.8-py2.py3-none-any.whl (183 kB)
     |████████████████████████████████| 183 kB 576 kB/s 
Collecting pytz>dev
  Downloading pytz-2019.3-py2.py3-none-any.whl (509 kB)
     |████████████████████████████████| 509 kB 1.6 MB/s 
Collecting vine==1.3.0
  Downloading vine-1.3.0-py2.py3-none-any.whl (14 kB)
Collecting redis>=3.2.0; extra == "redis"
  Downloading redis-3.4.1-py2.py3-none-any.whl (71 kB)
     |████████████████████████████████| 71 kB 8.1 MB/s 
Collecting cycler>=0.10
  Downloading cycler-0.10.0-py2.py3-none-any.whl (6.5 kB)
Collecting pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1
  Downloading pyparsing-2.4.7-py2.py3-none-any.whl (67 kB)
     |████████████████████████████████| 67 kB 7.7 MB/s 
Collecting numpy>=1.11
  Downloading numpy-1.18.2-cp38-cp38-manylinux1_x86_64.whl (20.6 MB)
     |████████████████████████████████| 20.6 MB 245 kB/s 
Collecting python-dateutil>=2.1
  Downloading python_dateutil-2.8.1-py2.py3-none-any.whl (227 kB)
     |████████████████████████████████| 227 kB 578 kB/s 
Collecting kiwisolver>=1.0.1
  Downloading kiwisolver-1.2.0-cp38-cp38-manylinux1_x86_64.whl (92 kB)
     |████████████████████████████████| 92 kB 110 kB/s 
Collecting pandas>=0.22.0
  Downloading pandas-1.0.3-cp38-cp38-manylinux1_x86_64.whl (10.0 MB)
     |████████████████████████████████| 10.0 MB 1.2 MB/s 
Collecting scipy>=1.0.1
  Downloading scipy-1.4.1-cp38-cp38-manylinux1_x86_64.whl (26.0 MB)
     |████████████████████████████████| 26.0 MB 1.6 MB/s 
Collecting alabaster<0.8,>=0.7
  Downloading alabaster-0.7.12-py2.py3-none-any.whl (14 kB)
Collecting imagesize
  Downloading imagesize-1.2.0-py2.py3-none-any.whl (4.8 kB)
Requirement already satisfied: setuptools in /usr/local/lib/python3.8/site-packages (from sphinx>=1.8.0b1->-r docs-requirements.txt (line 4)) (46.1.3)
Collecting docutils>=0.12
  Downloading docutils-0.16-py2.py3-none-any.whl (548 kB)
     |████████████████████████████████| 548 kB 1.5 MB/s 
Collecting requests>=2.5.0
  Downloading requests-2.23.0-py2.py3-none-any.whl (58 kB)
     |████████████████████████████████| 58 kB 8.7 MB/s 
Collecting sphinxcontrib-htmlhelp
  Downloading sphinxcontrib_htmlhelp-1.0.3-py2.py3-none-any.whl (96 kB)
     |████████████████████████████████| 96 kB 1.3 MB/s 
Collecting sphinxcontrib-jsmath
  Downloading sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl (5.1 kB)
Collecting sphinxcontrib-serializinghtml
  Downloading sphinxcontrib_serializinghtml-1.1.4-py2.py3-none-any.whl (89 kB)
     |████████████████████████████████| 89 kB 1.4 MB/s 
Collecting sphinxcontrib-qthelp
  Downloading sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl (90 kB)
     |████████████████████████████████| 90 kB 1.3 MB/s 
Collecting sphinxcontrib-applehelp
  Downloading sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl (121 kB)
     |████████████████████████████████| 121 kB 1.5 MB/s 
Collecting babel>=1.3
  Downloading Babel-2.8.0-py2.py3-none-any.whl (8.6 MB)
     |████████████████████████████████| 8.6 MB 1.8 MB/s 
Collecting sphinxcontrib-devhelp
  Downloading sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl (84 kB)
     |████████████████████████████████| 84 kB 3.8 MB/s 
Collecting snowballstemmer>=1.1
  Downloading snowballstemmer-2.0.0-py2.py3-none-any.whl (97 kB)
     |████████████████████████████████| 97 kB 1.4 MB/s 
Collecting packaging
  Downloading packaging-20.3-py2.py3-none-any.whl (37 kB)
Collecting Pygments>=2.0
  Downloading Pygments-2.6.1-py3-none-any.whl (914 kB)
     |████████████████████████████████| 914 kB 489 kB/s 
Collecting Jinja2>=2.3
  Downloading Jinja2-2.11.1-py2.py3-none-any.whl (126 kB)
     |████████████████████████████████| 126 kB 1.2 MB/s 
Collecting amqp<2.6,>=2.5.2
  Downloading amqp-2.5.2-py2.py3-none-any.whl (49 kB)
     |████████████████████████████████| 49 kB 4.6 MB/s 
Collecting six
  Downloading six-1.14.0-py2.py3-none-any.whl (10 kB)
Collecting chardet<4,>=3.0.2
  Downloading chardet-3.0.4-py2.py3-none-any.whl (133 kB)
     |████████████████████████████████| 133 kB 1.5 MB/s 
Collecting idna<3,>=2.5
  Downloading idna-2.9-py2.py3-none-any.whl (58 kB)
     |████████████████████████████████| 58 kB 6.9 MB/s 
Collecting certifi>=2017.4.17
  Downloading certifi-2020.4.5.1-py2.py3-none-any.whl (157 kB)
     |████████████████████████████████| 157 kB 762 kB/s 
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1
  Downloading urllib3-1.25.8-py2.py3-none-any.whl (125 kB)
     |████████████████████████████████| 125 kB 1.5 MB/s 
Collecting MarkupSafe>=0.23
  Downloading MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl (32 kB)
Installing collected packages: billiard, vine, amqp, kombu, pytz, redis, celery, six, cycler, pyparsing, numpy, python-dateutil, kiwisolver, matplotlib, pandas, scipy, seaborn, alabaster, imagesize, docutils, chardet, idna, certifi, urllib3, requests, sphinxcontrib-htmlhelp, sphinxcontrib-jsmath, sphinxcontrib-serializinghtml, sphinxcontrib-qthelp, sphinxcontrib-applehelp, babel, sphinxcontrib-devhelp, snowballstemmer, packaging, Pygments, MarkupSafe, Jinja2, sphinx
Successfully installed Jinja2-2.11.1 MarkupSafe-1.1.1 Pygments-2.6.1 alabaster-0.7.12 amqp-2.5.2 babel-2.8.0 billiard-3.6.3.0 celery-4.4.0 certifi-2020.4.5.1 chardet-3.0.4 cycler-0.10.0 docutils-0.16 idna-2.9 imagesize-1.2.0 kiwisolver-1.2.0 kombu-4.6.8 matplotlib-3.2.1 numpy-1.18.2 packaging-20.3 pandas-1.0.3 pyparsing-2.4.7 python-dateutil-2.8.1 pytz-2019.3 redis-3.4.1 requests-2.23.0 scipy-1.4.1 seaborn-0.10.0 six-1.14.0 snowballstemmer-2.0.0 sphinx-3.0.0 sphinxcontrib-applehelp-1.0.2 sphinxcontrib-devhelp-1.0.2 sphinxcontrib-htmlhelp-1.0.3 sphinxcontrib-jsmath-1.0.1 sphinxcontrib-qthelp-1.0.3 sphinxcontrib-serializinghtml-1.1.4 urllib3-1.25.8 vine-1.3.0
root@da57b757740e:/gwcelery# python setup.py build_sphinx
running build_sphinx
Running Sphinx v3.0.0
making output directory... done
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://celery.readthedocs.io/en/latest/objects.inv...
loading intersphinx inventory from https://comet.readthedocs.io/en/stable/objects.inv...
loading intersphinx inventory from https://docs.ligo.org/detchar/data-quality-report/objects.inv...
loading intersphinx inventory from https://htcondor.readthedocs.io/en/stable/objects.inv...
loading intersphinx inventory from https://gwpy.github.io/docs/stable/objects.inv...
loading intersphinx inventory from https://lscsoft.docs.ligo.org/ligo.skymap/objects.inv...
loading intersphinx inventory from https://requests.readthedocs.io/en/master/objects.inv...
loading intersphinx inventory from https://twistedmatrix.com/documents/current/api/objects.inv...
loading intersphinx inventory from https://emfollow.docs.ligo.org/userguide/objects.inv...
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 39 source files that are out of date
updating environment: [new config] 39 added, 0 changed, 0 removed
reading sources... [ 30%] gwcelery.tasks.bayestar                               
Exception occurred:
  File "/usr/local/lib/python3.8/inspect.py", line 524, in unwrap
    raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
ValueError: wrapper loop when unwrapping ligo.skymap.io.events
The full traceback has been saved in /tmp/sphinx-err-tpjn3lr4.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!
root@da57b757740e:/gwcelery# cat /tmp/sphinx-err-tpjn3lr4.log
# Sphinx version: 3.0.0
# Python version: 3.8.2 (CPython)
# Docutils version: 0.16 release
# Jinja2 version: 2.11.1
# Last messages:
#   reading sources... [  7%] contributing
#   reading sources... [ 10%] deployment
#   reading sources... [ 12%] design
#   reading sources... [ 15%] gwcelery
#   reading sources... [ 17%] gwcelery.conf
#   reading sources... [ 20%] gwcelery.email
#   reading sources... [ 23%] gwcelery.lvalert
#   reading sources... [ 25%] gwcelery.sentry
#   reading sources... [ 28%] gwcelery.tasks
#   reading sources... [ 30%] gwcelery.tasks.bayestar
# Loaded extensions:
#   sphinx.ext.mathjax (3.0.0) from /usr/local/lib/python3.8/site-packages/sphinx/ext/mathjax.py
#   sphinxcontrib.applehelp (1.0.2) from /usr/local/lib/python3.8/site-packages/sphinxcontrib/applehelp/__init__.py
#   sphinxcontrib.devhelp (1.0.2) from /usr/local/lib/python3.8/site-packages/sphinxcontrib/devhelp/__init__.py
#   sphinxcontrib.htmlhelp (1.0.3) from /usr/local/lib/python3.8/site-packages/sphinxcontrib/htmlhelp/__init__.py
#   sphinxcontrib.serializinghtml (1.1.4) from /usr/local/lib/python3.8/site-packages/sphinxcontrib/serializinghtml/__init__.py
#   sphinxcontrib.qthelp (1.0.3) from /usr/local/lib/python3.8/site-packages/sphinxcontrib/qthelp/__init__.py
#   alabaster (0.7.12) from /usr/local/lib/python3.8/site-packages/alabaster/__init__.py
#   sphinx.ext.autodoc.type_comment (3.0.0) from /usr/local/lib/python3.8/site-packages/sphinx/ext/autodoc/type_comment.py
#   sphinx.ext.autodoc (3.0.0) from /usr/local/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py
#   celery.contrib.sphinx (unknown version) from /usr/local/lib/python3.8/site-packages/celery/contrib/sphinx.py
#   matplotlib.sphinxext.plot_directive (3.2.1) from /usr/local/lib/python3.8/site-packages/matplotlib/sphinxext/plot_directive.py
#   sphinx.ext.extlinks (3.0.0) from /usr/local/lib/python3.8/site-packages/sphinx/ext/extlinks.py
#   sphinx.ext.graphviz (3.0.0) from /usr/local/lib/python3.8/site-packages/sphinx/ext/graphviz.py
#   sphinx.ext.intersphinx (3.0.0) from /usr/local/lib/python3.8/site-packages/sphinx/ext/intersphinx.py
#   sphinx.ext.napoleon (3.0.0) from /usr/local/lib/python3.8/site-packages/sphinx/ext/napoleon/__init__.py
#   sphinx.ext.viewcode (3.0.0) from /usr/local/lib/python3.8/site-packages/sphinx/ext/viewcode.py
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/sphinx/setup_command.py", line 193, in run
    app.build(force_all=self.all_files)
  File "/usr/local/lib/python3.8/site-packages/sphinx/application.py", line 348, in build
    self.builder.build_update()
  File "/usr/local/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 297, in build_update
    self.build(to_build,
  File "/usr/local/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 311, in build
    updated_docnames = set(self.read())
  File "/usr/local/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 418, in read
    self._read_serial(docnames)
  File "/usr/local/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 439, in _read_serial
    self.read_doc(docname)
  File "/usr/local/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 479, in read_doc
    doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
  File "/usr/local/lib/python3.8/site-packages/sphinx/io.py", line 221, in read_doc
    pub.publish()
  File "/usr/local/lib/python3.8/site-packages/docutils/core.py", line 217, in publish
    self.document = self.reader.read(self.source, self.parser,
  File "/usr/local/lib/python3.8/site-packages/sphinx/io.py", line 126, in read
    self.parse()
  File "/usr/local/lib/python3.8/site-packages/docutils/readers/__init__.py", line 77, in parse
    self.parser.parse(self.input, document)
  File "/usr/local/lib/python3.8/site-packages/sphinx/parsers.py", line 102, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/usr/local/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 170, in run
    results = StateMachineWS.run(self, input_lines, input_offset,
  File "/usr/local/lib/python3.8/site-packages/docutils/statemachine.py", line 241, in run
    context, next_state, result = self.check_line(
  File "/usr/local/lib/python3.8/site-packages/docutils/statemachine.py", line 459, in check_line
    return method(match, context, next_state)
  File "/usr/local/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/usr/local/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/usr/local/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
    newabsoffset = self.nested_parse(
  File "/usr/local/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/usr/local/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/usr/local/lib/python3.8/site-packages/docutils/statemachine.py", line 241, in run
    context, next_state, result = self.check_line(
  File "/usr/local/lib/python3.8/site-packages/docutils/statemachine.py", line 459, in check_line
    return method(match, context, next_state)
  File "/usr/local/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2342, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/usr/local/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
    return method(self, expmatch)
  File "/usr/local/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2096, in directive
    return self.run_directive(
  File "/usr/local/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
    result = directive_instance.run()
  File "/usr/local/lib/python3.8/site-packages/sphinx/ext/autodoc/directive.py", line 146, in run
    documenter.generate(more_content=self.content)
  File "/usr/local/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 769, in generate
    self.document_members(all_members)
  File "/usr/local/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 660, in document_members
    classes = [cls for cls in self.documenters.values()
  File "/usr/local/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 661, in <listcomp>
    if cls.can_document_member(member, mname, isattr, self)]
  File "/usr/local/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 1553, in can_document_member
    if inspect.isattributedescriptor(member):
  File "/usr/local/lib/python3.8/site-packages/sphinx/util/inspect.py", line 220, in isattributedescriptor
    unwrapped = inspect.unwrap(obj)
  File "/usr/local/lib/python3.8/inspect.py", line 524, in unwrap
    raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
ValueError: wrapper loop when unwrapping ligo.skymap.io.events

Expected behavior Successful build with no error messages.

Your project https://git.ligo.org/emfollow/gwcelery

Screenshots N/A

Environment info

stmcginnis commented 4 years ago

Same failure in the openstack/cinder repo:

http://paste.openstack.org/show/791673/ https://opendev.org/openstack/cinder/src/branch/master/doc/source/conf.py

JanuszL commented 4 years ago

I think the problem is with mocked modules. At least in my case. When you mock some module and then use it like from MOCKED_MODULE_NAME as SOME_SHORT_NAME, mocked module becomes an attribute that goes through isattributedescriptor which calls unwrap. unwrap inspects object looking for __wrapped__ property and the mocked module is a yes man, when asked for this property is just adds one and returns self jumping into an infinite loop. Maybe isattributedescriptor should check if it is a mock before calling unwrap?

doomb0t commented 4 years ago

I too am experiencing this after rebuilding my virtualenv with sphinx 3.0, perhaps something helpful:

If I add a submodule to the autodoc_mock_imports like this: markdown.Markdown no exception is thrown (but then generation is broken) same for any other submodule/module combination

sedoris commented 4 years ago

Same error for me too (well, I compared 2.4.4 to 3.0.0). I also tried import pandas instead of import pandas as pd, but that didn't fix the problem.

conf.py

import os
import sys

sys.path.insert(0, os.path.abspath('../..'))
extensions = ['sphinx.ext.autodoc']

source_suffix = '.rst'
master_doc = 'index'

autodoc_mock_imports = ["pandas"]

example.py

import pandas

def sample_function():
    print('hello world')
    return
tk0miya commented 4 years ago

Sorry for the inconvenience. and thank you for the detailed report. I just post #7431 to fix this. Please try it if you have time.