Merge branch '2.0'

This commit is contained in:
Takeshi KOMIYA 2019-07-13 11:17:35 +09:00
commit a498960de9
16 changed files with 51 additions and 34 deletions

View File

@ -81,6 +81,8 @@ Bugs fixed
* #6527: :confval:`last_updated` wrongly assumes timezone as UTC * #6527: :confval:`last_updated` wrongly assumes timezone as UTC
* #5592: std domain: :rst:dir:`option` directive registers an index entry for * #5592: std domain: :rst:dir:`option` directive registers an index entry for
each comma separated option each comma separated option
* #6549: sphinx-build: Escaped characters in error messages
* #6545: doctest comments not getting trimmed since Sphinx 1.8.0
Testing Testing
-------- --------

View File

@ -47,7 +47,7 @@ extras_require = {
'html5lib', 'html5lib',
'flake8>=3.5.0', 'flake8>=3.5.0',
'flake8-import-order', 'flake8-import-order',
'mypy>=0.711', 'mypy>=0.720',
'docutils-stubs', 'docutils-stubs',
], ],
} }

View File

@ -47,7 +47,7 @@ def handle_exception(app: Sphinx, args: Any, exception: BaseException, stderr: I
print(terminal_safe(exception.args[0]), file=stderr) print(terminal_safe(exception.args[0]), file=stderr)
elif isinstance(exception, SphinxError): elif isinstance(exception, SphinxError):
print(red('%s:' % exception.category), file=stderr) print(red('%s:' % exception.category), file=stderr)
print(terminal_safe(str(exception)), file=stderr) print(str(exception), file=stderr)
elif isinstance(exception, UnicodeError): elif isinstance(exception, UnicodeError):
print(red(__('Encoding error:')), file=stderr) print(red(__('Encoding error:')), file=stderr)
print(terminal_safe(str(exception)), file=stderr) print(terminal_safe(str(exception)), file=stderr)

View File

@ -285,7 +285,7 @@ class DocTestBuilder(Builder):
# for doctest examples but unusable for multi-statement code such # for doctest examples but unusable for multi-statement code such
# as setup code -- to be able to use doctest error reporting with # as setup code -- to be able to use doctest error reporting with
# that code nevertheless, we monkey-patch the "compile" it uses. # that code nevertheless, we monkey-patch the "compile" it uses.
doctest.compile = self.compile # type: ignore doctest.compile = self.compile
sys.path[0:0] = self.config.doctest_path sys.path[0:0] = self.config.doctest_path

View File

@ -399,6 +399,6 @@ def inspect_main(argv: List[str]) -> None:
if __name__ == '__main__': if __name__ == '__main__':
import logging # type: ignore import logging # type: ignore
logging.basicConfig() # type: ignore logging.basicConfig()
inspect_main(argv=sys.argv[1:]) inspect_main(argv=sys.argv[1:])

View File

@ -159,7 +159,7 @@ class TodoListProcessor:
self.process(doctree, docname) self.process(doctree, docname)
def process(self, doctree: nodes.document, docname: str) -> None: def process(self, doctree: nodes.document, docname: str) -> None:
todos = sum(self.domain.todos.values(), []) todos = sum(self.domain.todos.values(), []) # type: List[todo_node]
for node in doctree.traverse(todolist): for node in doctree.traverse(todolist):
if not self.config.todo_include_todos: if not self.config.todo_include_todos:
node.parent.remove(node) node.parent.remove(node)
@ -220,7 +220,7 @@ def process_todo_nodes(app: Sphinx, doctree: nodes.document, fromdocname: str) -
warnings.warn('process_todo_nodes() is deprecated.', RemovedInSphinx40Warning) warnings.warn('process_todo_nodes() is deprecated.', RemovedInSphinx40Warning)
domain = cast(TodoDomain, app.env.get_domain('todo')) domain = cast(TodoDomain, app.env.get_domain('todo'))
todos = sum(domain.todos.values(), []) todos = sum(domain.todos.values(), []) # type: List[todo_node]
for node in doctree.traverse(todolist): for node in doctree.traverse(todolist):
if node.get('ids'): if node.get('ids'):

View File

@ -274,7 +274,7 @@ class VariableCommentPicker(ast.NodeVisitor):
"""Handles Assign node and pick up a variable comment.""" """Handles Assign node and pick up a variable comment."""
try: try:
targets = get_assign_targets(node) targets = get_assign_targets(node)
varnames = sum([get_lvar_names(t, self=self.get_self()) for t in targets], []) varnames = sum([get_lvar_names(t, self=self.get_self()) for t in targets], []) # type: List[str] # NOQA
current_line = self.get_line(node.lineno) current_line = self.get_line(node.lineno)
except TypeError: except TypeError:
return # this assignment is not new definition! return # this assignment is not new definition!

View File

@ -400,7 +400,7 @@ class GUILabel(SphinxRole):
class MenuSelection(GUILabel): class MenuSelection(GUILabel):
def run(self): def run(self):
# type: () -> Tuple[List[nodes.Node], List[nodes.system_message]] # type: () -> Tuple[List[nodes.Node], List[nodes.system_message]]
self.text = self.text.replace('-->', '\N{TRIANGULAR BULLET}') # type: ignore self.text = self.text.replace('-->', '\N{TRIANGULAR BULLET}')
return super().run() return super().run()

View File

@ -120,8 +120,8 @@ class SphinxTestApp(application.Sphinx):
warningiserror = False warningiserror = False
self._saved_path = sys.path[:] self._saved_path = sys.path[:]
self._saved_directives = directives._directives.copy() # type: ignore self._saved_directives = directives._directives.copy()
self._saved_roles = roles._roles.copy() # type: ignore self._saved_roles = roles._roles.copy()
self._saved_nodeclasses = {v for v in dir(nodes.GenericNodeVisitor) self._saved_nodeclasses = {v for v in dir(nodes.GenericNodeVisitor)
if v.startswith('visit_')} if v.startswith('visit_')}
@ -140,8 +140,8 @@ class SphinxTestApp(application.Sphinx):
locale.translators.clear() locale.translators.clear()
sys.path[:] = self._saved_path sys.path[:] = self._saved_path
sys.modules.pop('autodoc_fodder', None) sys.modules.pop('autodoc_fodder', None)
directives._directives = self._saved_directives # type: ignore directives._directives = self._saved_directives
roles._roles = self._saved_roles # type: ignore roles._roles = self._saved_roles
for method in dir(nodes.GenericNodeVisitor): for method in dir(nodes.GenericNodeVisitor):
if method.startswith('visit_') and \ if method.startswith('visit_') and \
method not in self._saved_nodeclasses: method not in self._saved_nodeclasses:

View File

@ -9,7 +9,7 @@
""" """
import sys import sys
from typing import NamedTuple from typing import NamedTuple, Union
from docutils import nodes from docutils import nodes
from pygments.lexers import PythonConsoleLexer, guess_lexer from pygments.lexers import PythonConsoleLexer, guess_lexer
@ -110,13 +110,21 @@ class TrimDoctestFlagsTransform(SphinxTransform):
if not self.config.trim_doctest_flags: if not self.config.trim_doctest_flags:
return return
for node in self.document.traverse(nodes.literal_block): for lbnode in self.document.traverse(nodes.literal_block): # type: nodes.literal_block
if self.is_pyconsole(node): if self.is_pyconsole(lbnode):
source = node.rawsource self.strip_doctest_flags(lbnode)
source = doctest.blankline_re.sub('', source)
source = doctest.doctestopt_re.sub('', source) for dbnode in self.document.traverse(nodes.doctest_block): # type: nodes.doctest_block
node.rawsource = source self.strip_doctest_flags(dbnode)
node[:] = [nodes.Text(source)]
@staticmethod
def strip_doctest_flags(node):
# type: (Union[nodes.literal_block, nodes.doctest_block]) -> None
source = node.rawsource
source = doctest.blankline_re.sub('', source)
source = doctest.doctestopt_re.sub('', source)
node.rawsource = source
node[:] = [nodes.Text(source)]
@staticmethod @staticmethod
def is_pyconsole(node): def is_pyconsole(node):

View File

@ -220,7 +220,7 @@ def save_traceback(app: "Sphinx") -> str:
platform.python_version(), platform.python_version(),
platform.python_implementation(), platform.python_implementation(),
docutils.__version__, docutils.__version_details__, docutils.__version__, docutils.__version_details__,
jinja2.__version__, # type: ignore jinja2.__version__,
last_msgs)).encode()) last_msgs)).encode())
if app is not None: if app is not None:
for ext in app.extensions.values(): for ext in app.extensions.values():

View File

@ -49,13 +49,13 @@ additional_nodes = set() # type: Set[Type[nodes.Element]]
def docutils_namespace() -> Generator[None, None, None]: def docutils_namespace() -> Generator[None, None, None]:
"""Create namespace for reST parsers.""" """Create namespace for reST parsers."""
try: try:
_directives = copy(directives._directives) # type: ignore _directives = copy(directives._directives)
_roles = copy(roles._roles) # type: ignore _roles = copy(roles._roles)
yield yield
finally: finally:
directives._directives = _directives # type: ignore directives._directives = _directives
roles._roles = _roles # type: ignore roles._roles = _roles
for node in list(additional_nodes): for node in list(additional_nodes):
unregister_node(node) unregister_node(node)
@ -64,7 +64,7 @@ def docutils_namespace() -> Generator[None, None, None]:
def is_directive_registered(name: str) -> bool: def is_directive_registered(name: str) -> bool:
"""Check the *name* directive is already registered.""" """Check the *name* directive is already registered."""
return name in directives._directives # type: ignore return name in directives._directives
def register_directive(name: str, directive: Type[Directive]) -> None: def register_directive(name: str, directive: Type[Directive]) -> None:
@ -78,7 +78,7 @@ def register_directive(name: str, directive: Type[Directive]) -> None:
def is_role_registered(name: str) -> bool: def is_role_registered(name: str) -> bool:
"""Check the *name* role is already registered.""" """Check the *name* role is already registered."""
return name in roles._roles # type: ignore return name in roles._roles
def register_role(name: str, role: RoleFunction) -> None: def register_role(name: str, role: RoleFunction) -> None:
@ -92,7 +92,7 @@ def register_role(name: str, role: RoleFunction) -> None:
def unregister_role(name: str) -> None: def unregister_role(name: str) -> None:
"""Unregister a role from docutils.""" """Unregister a role from docutils."""
roles._roles.pop(name, None) # type: ignore roles._roles.pop(name, None)
def is_node_registered(node: Type[Element]) -> bool: def is_node_registered(node: Type[Element]) -> bool:
@ -107,7 +107,7 @@ def register_node(node: Type[Element]) -> None:
inside ``docutils_namespace()`` to prevent side-effects. inside ``docutils_namespace()`` to prevent side-effects.
""" """
if not hasattr(nodes.GenericNodeVisitor, 'visit_' + node.__name__): if not hasattr(nodes.GenericNodeVisitor, 'visit_' + node.__name__):
nodes._add_node_class_names([node.__name__]) # type: ignore nodes._add_node_class_names([node.__name__])
additional_nodes.add(node) additional_nodes.add(node)

View File

@ -514,7 +514,7 @@ class Signature:
qualname = repr(annotation) qualname = repr(annotation)
if (hasattr(typing, 'TupleMeta') and if (hasattr(typing, 'TupleMeta') and
isinstance(annotation, typing.TupleMeta) and # type: ignore isinstance(annotation, typing.TupleMeta) and
not hasattr(annotation, '__tuple_params__')): not hasattr(annotation, '__tuple_params__')):
# This is for Python 3.6+, 3.5 case is handled below # This is for Python 3.6+, 3.5 case is handled below
params = annotation.__args__ params = annotation.__args__
@ -545,7 +545,7 @@ class Signature:
param_str = ', '.join(self.format_annotation(p) for p in params) param_str = ', '.join(self.format_annotation(p) for p in params)
return '%s[%s]' % (qualname, param_str) return '%s[%s]' % (qualname, param_str)
elif (hasattr(typing, 'UnionMeta') and # for py35 or below elif (hasattr(typing, 'UnionMeta') and # for py35 or below
isinstance(annotation, typing.UnionMeta) and # type: ignore isinstance(annotation, typing.UnionMeta) and
hasattr(annotation, '__union_params__')): hasattr(annotation, '__union_params__')):
params = annotation.__union_params__ params = annotation.__union_params__
if params is not None: if params is not None:
@ -565,7 +565,7 @@ class Signature:
param_str = ', '.join(self.format_annotation(p) for p in params) param_str = ', '.join(self.format_annotation(p) for p in params)
return 'Union[%s]' % param_str return 'Union[%s]' % param_str
elif (hasattr(typing, 'CallableMeta') and # for py36 or below elif (hasattr(typing, 'CallableMeta') and # for py36 or below
isinstance(annotation, typing.CallableMeta) and # type: ignore isinstance(annotation, typing.CallableMeta) and
getattr(annotation, '__args__', None) is not None and getattr(annotation, '__args__', None) is not None and
hasattr(annotation, '__result__')): hasattr(annotation, '__result__')):
# Skipped in the case of plain typing.Callable # Skipped in the case of plain typing.Callable
@ -581,7 +581,7 @@ class Signature:
args_str, args_str,
self.format_annotation(annotation.__result__)) self.format_annotation(annotation.__result__))
elif (hasattr(typing, 'TupleMeta') and # for py36 or below elif (hasattr(typing, 'TupleMeta') and # for py36 or below
isinstance(annotation, typing.TupleMeta) and # type: ignore isinstance(annotation, typing.TupleMeta) and
hasattr(annotation, '__tuple_params__') and hasattr(annotation, '__tuple_params__') and
hasattr(annotation, '__tuple_use_ellipsis__')): hasattr(annotation, '__tuple_use_ellipsis__')):
params = annotation.__tuple_params__ params = annotation.__tuple_params__

View File

@ -375,7 +375,7 @@ class TextWriter(writers.Writer):
settings_spec = ('No options here.', '', ()) settings_spec = ('No options here.', '', ())
settings_defaults = {} # type: Dict settings_defaults = {} # type: Dict
output = None output = None # type: str
def __init__(self, builder): def __init__(self, builder):
# type: (TextBuilder) -> None # type: (TextBuilder) -> None

View File

@ -21,3 +21,8 @@ test-trim_doctest_flags
>>> datetime.date.now() # doctest: +QUX >>> datetime.date.now() # doctest: +QUX
datetime.date(2008, 1, 1) datetime.date(2008, 1, 1)
.. doctest_block::
>>> datetime.date.now() # doctest: +QUUX
datetime.date(2008, 1, 1)

View File

@ -18,6 +18,7 @@ def test_trim_doctest_flags_html(app, status, warning):
assert 'BAR' in result assert 'BAR' in result
assert 'BAZ' not in result assert 'BAZ' not in result
assert 'QUX' not in result assert 'QUX' not in result
assert 'QUUX' not in result
@pytest.mark.sphinx('latex', testroot='trim_doctest_flags') @pytest.mark.sphinx('latex', testroot='trim_doctest_flags')
@ -29,3 +30,4 @@ def test_trim_doctest_flags_latex(app, status, warning):
assert 'BAR' in result assert 'BAR' in result
assert 'BAZ' not in result assert 'BAZ' not in result
assert 'QUX' not in result assert 'QUX' not in result
assert 'QUUX' not in result