mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix sphinx.ext.autodoc
crashes if target code imports * from mock modules by autodoc_mock_imports
This commit is contained in:
parent
54dd5c5fd1
commit
e15216c568
2
CHANGES
2
CHANGES
@ -101,6 +101,8 @@ Bugs fixed
|
||||
* #2707: (latex) the column width is badly computed for tabular
|
||||
* #2799: Sphinx installs roles and directives automatically on importing sphinx
|
||||
module. Now Sphinx installs them on running application.
|
||||
* `sphinx.ext.autodoc` crashes if target code imports * from mock modules
|
||||
by `autodoc_mock_imports`.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
@ -86,17 +86,21 @@ class Options(dict):
|
||||
|
||||
class _MockModule(object):
|
||||
"""Used by autodoc_mock_imports."""
|
||||
__file__ = '/dev/null'
|
||||
__path__ = '/dev/null'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
self.__all__ = []
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return _MockModule()
|
||||
|
||||
def _append_submodule(self, submod):
|
||||
self.__all__.append(submod)
|
||||
|
||||
@classmethod
|
||||
def __getattr__(cls, name):
|
||||
if name in ('__file__', '__path__'):
|
||||
return '/dev/null'
|
||||
elif name[0] == name[0].upper():
|
||||
if name[0] == name[0].upper():
|
||||
# Not very good, we assume Uppercase names are classes...
|
||||
mocktype = type(name, (), {})
|
||||
mocktype.__module__ = __name__
|
||||
@ -109,9 +113,12 @@ def mock_import(modname):
|
||||
if '.' in modname:
|
||||
pkg, _n, mods = modname.rpartition('.')
|
||||
mock_import(pkg)
|
||||
mod = _MockModule()
|
||||
sys.modules[modname] = mod
|
||||
return mod
|
||||
if isinstance(sys.modules[pkg], _MockModule):
|
||||
sys.modules[pkg]._append_submodule(mods)
|
||||
|
||||
if modname not in sys.modules:
|
||||
mod = _MockModule()
|
||||
sys.modules[modname] = mod
|
||||
|
||||
|
||||
ALL = object()
|
||||
@ -514,7 +521,7 @@ class Documenter(object):
|
||||
try:
|
||||
dbg('[autodoc] import %s', self.modname)
|
||||
for modname in self.env.config.autodoc_mock_imports:
|
||||
dbg('[autodoc] adding a mock module %s!', self.modname)
|
||||
dbg('[autodoc] adding a mock module %s!', modname)
|
||||
mock_import(modname)
|
||||
__import__(self.modname)
|
||||
parent = None
|
||||
|
6
tests/roots/test-ext-autodoc/autodoc_dummy_module.py
Normal file
6
tests/roots/test-ext-autodoc/autodoc_dummy_module.py
Normal file
@ -0,0 +1,6 @@
|
||||
from dummy import *
|
||||
|
||||
|
||||
def test():
|
||||
"""Dummy function using dummy.*"""
|
||||
dummy_function()
|
12
tests/roots/test-ext-autodoc/conf.py
Normal file
12
tests/roots/test-ext-autodoc/conf.py
Normal file
@ -0,0 +1,12 @@
|
||||
import sys, os
|
||||
|
||||
sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
extensions = ['sphinx.ext.autodoc']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
autodoc_mock_imports = [
|
||||
'dummy'
|
||||
]
|
3
tests/roots/test-ext-autodoc/contents.rst
Normal file
3
tests/roots/test-ext-autodoc/contents.rst
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
.. automodule:: autodoc_dummy_module
|
||||
:members:
|
25
tests/test_ext_autodoc.py
Normal file
25
tests/test_ext_autodoc.py
Normal file
@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
test_autodoc
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Test the autodoc extension.
|
||||
|
||||
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
import pickle
|
||||
from docutils import nodes
|
||||
from sphinx import addnodes
|
||||
from util import with_app
|
||||
|
||||
|
||||
@with_app(buildername='dummy', testroot='ext-autodoc')
|
||||
def test_autodoc(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
content = pickle.loads((app.doctreedir / 'contents.doctree').bytes())
|
||||
assert isinstance(content[3], addnodes.desc)
|
||||
assert content[3][0].astext() == 'autodoc_dummy_module.test'
|
||||
assert content[3][1].astext() == 'Dummy function using dummy.*'
|
Loading…
Reference in New Issue
Block a user