summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2014-01-19 10:31:15 +0100
committerGeorg Brandl <georg@python.org>2014-01-19 10:31:15 +0100
commit005e3af772ef288af4a3cc029c4e9a8ff00d2ca0 (patch)
treebfa7571ce91ca4a5176bbef8cc3f8384469c6f32
parenta0f2548e011d7bca14ed0b8f148c47040d620227 (diff)
parent10e786edac3809660e9129fe53f5e7e05cc9429e (diff)
downloadsphinx-005e3af772ef288af4a3cc029c4e9a8ff00d2ca0.tar.gz
Merged in guibog/sphinx2 (pull request #184)
autodoc extension: add autodoc_mock_imports config value
-rw-r--r--doc/ext/autodoc.rst10
-rw-r--r--sphinx/ext/autodoc.py32
-rw-r--r--tests/root/autodoc.txt2
-rw-r--r--tests/root/autodoc_missing_imports.py9
-rw-r--r--tests/root/conf.py7
5 files changed, 60 insertions, 0 deletions
diff --git a/doc/ext/autodoc.rst b/doc/ext/autodoc.rst
index c92fe0c4..c37328f5 100644
--- a/doc/ext/autodoc.rst
+++ b/doc/ext/autodoc.rst
@@ -195,6 +195,10 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
.. versionadded:: 1.2
+ * Add a list of modules in the :confval:`autodoc_mock_imports` to prevent
+ import errors to halt the building process when some external dependencies
+ are not importable at build time.
+
.. rst:directive:: autofunction
autodata
@@ -335,6 +339,12 @@ There are also new config values that you can set:
.. versionadded:: 1.1
+.. confval:: autodoc_mock_imports
+
+ This value contains a list of modules to be mocked up. This is useful when
+ some external dependencies are not met at build time and break the building
+ process.
+
Docstring preprocessing
-----------------------
diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py
index 571f36cb..6c13e243 100644
--- a/sphinx/ext/autodoc.py
+++ b/sphinx/ext/autodoc.py
@@ -70,6 +70,26 @@ class Options(dict):
return None
+class _MockModule(object):
+ def __init__(self, *args, **kwargs):
+ pass
+
+ def __call__(self, *args, **kwargs):
+ return _MockModule()
+
+ @classmethod
+ def __getattr__(cls, name):
+ if name in ('__file__', '__path__'):
+ return '/dev/null'
+ elif name[0] == name[0].upper():
+ # Not very good, we assume Uppercase names are classes...
+ mocktype = type(name, (), {})
+ mocktype.__module__ = __name__
+ return mocktype
+ else:
+ return _MockModule()
+
+
ALL = object()
INSTANCEATTR = object()
@@ -332,6 +352,8 @@ class Documenter(object):
self.modname, '.'.join(self.objpath))
try:
dbg('[autodoc] import %s', self.modname)
+ for modname in self.env.config.autodoc_mock_imports:
+ self._mock_import(modname)
__import__(self.modname)
parent = None
obj = self.module = sys.modules[self.modname]
@@ -361,6 +383,15 @@ class Documenter(object):
self.env.note_reread()
return False
+ def _mock_import(self, modname):
+ if '.' in modname:
+ pkg, _n, mods = modname.rpartition('.')
+ self._mock_import(pkg)
+ mod = _MockModule()
+ sys.modules[modname] = mod
+ return mod
+
+
def get_real_modname(self):
"""Get the real module name of an object to document.
@@ -1453,6 +1484,7 @@ def setup(app):
app.add_config_value('autodoc_member_order', 'alphabetic', True)
app.add_config_value('autodoc_default_flags', [], True)
app.add_config_value('autodoc_docstring_signature', True, True)
+ app.add_config_value('autodoc_mock_imports', [], True)
app.add_event('autodoc-process-docstring')
app.add_event('autodoc-process-signature')
app.add_event('autodoc-skip-member')
diff --git a/tests/root/autodoc.txt b/tests/root/autodoc.txt
index d4b3404c..aa0dffba 100644
--- a/tests/root/autodoc.txt
+++ b/tests/root/autodoc.txt
@@ -45,3 +45,5 @@ Just testing a few autodoc possibilities...
:members: ca1, ia1
Specific members (2 total)
+
+.. automodule:: autodoc_missing_imports
diff --git a/tests/root/autodoc_missing_imports.py b/tests/root/autodoc_missing_imports.py
new file mode 100644
index 00000000..7a717345
--- /dev/null
+++ b/tests/root/autodoc_missing_imports.py
@@ -0,0 +1,9 @@
+
+import missing_module
+from missing_module import missing_name
+import missing_package1.missing_module1
+from missing_package2 import missing_module2
+from missing_package3.missing_module3 import missing_name
+
+class TestAutodoc(object):
+ """TestAutodoc docstring."""
diff --git a/tests/root/conf.py b/tests/root/conf.py
index 3399043f..cf88c2bb 100644
--- a/tests/root/conf.py
+++ b/tests/root/conf.py
@@ -71,6 +71,13 @@ autosummary_generate = ['autosummary']
extlinks = {'issue': ('http://bugs.python.org/issue%s', 'issue '),
'pyurl': ('http://python.org/%s', None)}
+autodoc_mock_imports = [
+ 'missing_module',
+ 'missing_package1.missing_module1',
+ 'missing_package2.missing_module2',
+ 'missing_package3.missing_module3',
+]
+
# modify tags from conf.py
tags.add('confpytag')