summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES2
-rw-r--r--doc/extdev/markupapi.rst22
-rw-r--r--sphinx/ext/autodoc/__init__.py5
-rw-r--r--sphinx/ext/autodoc/directive.py12
-rw-r--r--sphinx/util/docutils.py22
5 files changed, 51 insertions, 12 deletions
diff --git a/CHANGES b/CHANGES
index ed76ea4a7..73a75a894 100644
--- a/CHANGES
+++ b/CHANGES
@@ -19,6 +19,8 @@ Deprecated
* using a string value for :confval:`html_sidebars` is deprecated and only list
values will be accepted at 2.0.
+* ``sphinx.ext.autodoc.AutodocReporter`` is replaced by ``sphinx.util.docutils.
+ switch_source_input()`` and now deprecated. It will be removed in Sphinx-2.0.
Features added
--------------
diff --git a/doc/extdev/markupapi.rst b/doc/extdev/markupapi.rst
index df23f164d..8a18e2306 100644
--- a/doc/extdev/markupapi.rst
+++ b/doc/extdev/markupapi.rst
@@ -117,12 +117,30 @@ Both APIs parse the content into a given node. They are used like this::
node = docutils.nodes.paragraph()
# either
- from sphinx.ext.autodoc import AutodocReporter
- self.state.memo.reporter = AutodocReporter(self.result, self.state.memo.reporter) # override reporter to avoid errors from "include" directive
nested_parse_with_titles(self.state, self.result, node)
# or
self.state.nested_parse(self.result, 0, node)
+.. note::
+
+ ``sphinx.util.docutils.switch_source_input()`` allows to change a target file
+ during nested_parse. It is useful to mixture contents. For example, ``sphinx.
+ ext.autodoc`` uses it to parse docstrings.
+
+ from sphinx.util.docutils import switch_source_input
+
+ # Switch source_input between parsing content.
+ # Inside this context, all parsing errors and warnings are reported as
+ # happened in new source_input (in this case, ``self.result``).
+ with switch_source_input(self.state, self.result):
+ node = docutils.nodes.paragraph()
+ self.state.nested_parse(self.result, 0, node)
+
+ .. deprecated:: 1.7
+
+ Since Sphinx-1.6, ``sphinx.ext.autodoc.AutodocReporter`` is used for this purpose.
+ For now, it is replaced by ``switch_source_input()``.
+
If you don't need the wrapping node, you can use any concrete node type and
return ``node.children`` from the Directive.
diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py
index c74ca43c9..ebe929ea3 100644
--- a/sphinx/ext/autodoc/__init__.py
+++ b/sphinx/ext/autodoc/__init__.py
@@ -15,6 +15,7 @@ import re
import sys
import inspect
import traceback
+import warnings
from six import PY2, iterkeys, iteritems, itervalues, text_type, class_types, string_types
@@ -22,6 +23,7 @@ from docutils.parsers.rst import Directive
from docutils.statemachine import ViewList
import sphinx
+from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.ext.autodoc.importer import mock, import_module
from sphinx.ext.autodoc.importer import _MockImporter # to keep compatibility # NOQA
from sphinx.ext.autodoc.inspector import format_annotation, formatargspec # to keep compatibility # NOQA
@@ -112,6 +114,9 @@ class AutodocReporter(object):
"""
def __init__(self, viewlist, reporter):
# type: (ViewList, Reporter) -> None
+ warnings.warn('AutodocRerporter is now deprecated. '
+ 'Use sphinx.util.docutils.switch_source_input() instead.',
+ RemovedInSphinx20Warning)
self.viewlist = viewlist
self.reporter = reporter
diff --git a/sphinx/ext/autodoc/directive.py b/sphinx/ext/autodoc/directive.py
index f348e105a..78593d27c 100644
--- a/sphinx/ext/autodoc/directive.py
+++ b/sphinx/ext/autodoc/directive.py
@@ -12,8 +12,9 @@ from docutils.parsers.rst import Directive
from docutils.statemachine import ViewList
from docutils.utils import assemble_option_dict
-from sphinx.ext.autodoc import AutoDirective, AutodocReporter
+from sphinx.ext.autodoc import AutoDirective
from sphinx.util import logging
+from sphinx.util.docutils import switch_source_input
from sphinx.util.nodes import nested_parse_with_titles
if False:
@@ -82,12 +83,7 @@ def process_documenter_options(documenter, config, options):
def parse_generated_content(state, content, documenter):
# type: (State, StringList, Documenter) -> List[nodes.Node]
- try:
- # use a custom reporter that correctly assigns lines to source
- # filename/description and lineno
- old_reporter = state.memo.reporter
- state.memo.reporter = AutodocReporter(content, state.memo.reporter)
-
+ with switch_source_input(state, content):
if documenter.titles_allowed:
node = nodes.section()
# necessary so that the child nodes get the right source/line set
@@ -99,8 +95,6 @@ def parse_generated_content(state, content, documenter):
state.nested_parse(content, 0, node)
return node.children
- finally:
- state.memo.reporter = old_reporter
class AutodocDirective(Directive):
diff --git a/sphinx/util/docutils.py b/sphinx/util/docutils.py
index a745e058a..f4dd96158 100644
--- a/sphinx/util/docutils.py
+++ b/sphinx/util/docutils.py
@@ -18,7 +18,7 @@ from contextlib import contextmanager
import docutils
from docutils.languages import get_language
-from docutils.statemachine import ViewList
+from docutils.statemachine import StateMachine, ViewList
from docutils.parsers.rst import directives, roles, convert_directive_function
from docutils.utils import Reporter
@@ -33,6 +33,7 @@ if False:
# For type annotation
from typing import Any, Callable, Dict, Iterator, List, Tuple # NOQA
from docutils import nodes # NOQA
+ from docutils.statemachine import State # NOQA
from sphinx.environment import BuildEnvironment # NOQA
from sphinx.io import SphinxFileInput # NOQA
@@ -216,3 +217,22 @@ def directive_helper(obj, has_content=None, argument_spec=None, option_spec=None
raise ExtensionError(__('when adding directive classes, no '
'additional arguments may be given'))
return obj
+
+
+@contextmanager
+def switch_source_input(state, content):
+ # type: (State, ViewList) -> None
+ """Switch current source input of state temporarily."""
+ try:
+ # remember the original ``get_source_and_line()`` method
+ get_source_and_line = state.memo.reporter.get_source_and_line
+
+ # replace it by new one
+ state_machine = StateMachine([], None)
+ state_machine.input_lines = content
+ state.memo.reporter.get_source_and_line = state_machine.get_source_and_line
+
+ yield
+ finally:
+ # restore the method
+ state.memo.reporter.get_source_and_line = get_source_and_line