summaryrefslogtreecommitdiff
path: root/sphinx/ext/viewcode.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/ext/viewcode.py')
-rw-r--r--sphinx/ext/viewcode.py54
1 files changed, 40 insertions, 14 deletions
diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py
index 059aa5ef1..6d3c3c1c0 100644
--- a/sphinx/ext/viewcode.py
+++ b/sphinx/ext/viewcode.py
@@ -10,12 +10,14 @@
"""
import traceback
+import warnings
from docutils import nodes
from six import iteritems, text_type
import sphinx
from sphinx import addnodes
+from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.locale import _
from sphinx.pycode import ModuleAnalyzer
from sphinx.util import get_full_modname, logging, status_iterator
@@ -25,6 +27,7 @@ if False:
# For type annotation
from typing import Any, Dict, Iterable, Iterator, Set, Tuple # NOQA
from sphinx.application import Sphinx # NOQA
+ from sphinx.config import Config # NOQA
from sphinx.environment import BuildEnvironment # NOQA
logger = logging.getLogger(__name__)
@@ -61,20 +64,29 @@ def doctree_read(app, doctree):
def has_tag(modname, fullname, docname, refname):
entry = env._viewcode_modules.get(modname, None) # type: ignore
- try:
- analyzer = ModuleAnalyzer.for_module(modname)
- except Exception:
- env._viewcode_modules[modname] = False # type: ignore
- return
- if not isinstance(analyzer.code, text_type):
- code = analyzer.code.decode(analyzer.encoding)
- else:
- code = analyzer.code
if entry is False:
return
- elif entry is None or entry[0] != code:
+
+ code_tags = app.emit_firstresult('viewcode-find-source', modname)
+ if code_tags is None:
+ try:
+ analyzer = ModuleAnalyzer.for_module(modname)
+ except Exception:
+ env._viewcode_modules[modname] = False # type: ignore
+ return
+
+ if not isinstance(analyzer.code, text_type):
+ code = analyzer.code.decode(analyzer.encoding)
+ else:
+ code = analyzer.code
+
analyzer.find_tags()
- entry = code, analyzer.tags, {}, refname
+ tags = analyzer.tags
+ else:
+ code, tags = code_tags
+
+ if entry is None or entry[0] != code:
+ entry = code, tags, {}, refname
env._viewcode_modules[modname] = entry # type: ignore
_, tags, used, _ = entry
if fullname in tags:
@@ -91,7 +103,7 @@ def doctree_read(app, doctree):
modname = signode.get('module')
fullname = signode.get('fullname')
refname = modname
- if env.config.viewcode_import:
+ if env.config.viewcode_follow_imported_members:
modname = _get_full_modname(app, modname, fullname)
if not modname:
continue
@@ -230,14 +242,28 @@ def collect_pages(app):
yield ('_modules/index', context, 'page.html')
+def migrate_viewcode_import(app, config):
+ # type: (Sphinx, Config) -> None
+ if config.viewcode_import is not None:
+ warnings.warn('viewcode_import was renamed to viewcode_follow_imported_members. '
+ 'Please update your configuration.',
+ RemovedInSphinx30Warning)
+
+
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
- app.add_config_value('viewcode_import', True, False)
+ app.add_config_value('viewcode_import', None, False)
app.add_config_value('viewcode_enable_epub', False, False)
+ app.add_config_value('viewcode_follow_imported_members', True, False)
app.connect('doctree-read', doctree_read)
app.connect('env-merge-info', env_merge_info)
app.connect('html-collect-pages', collect_pages)
app.connect('missing-reference', missing_reference)
# app.add_config_value('viewcode_include_modules', [], 'env')
# app.add_config_value('viewcode_exclude_modules', [], 'env')
- return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
+ app.add_event('viewcode-find-source')
+ return {
+ 'version': sphinx.__display_version__,
+ 'env_version': 1,
+ 'parallel_read_safe': True
+ }