diff --git a/.circleci/config.yml b/.circleci/config.yml index f4d4415f1..d349db6e0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,6 +6,6 @@ jobs: working_directory: /sphinx steps: - checkout - - run: /python3.4/bin/pip install -U pip setuptools - - run: /python3.4/bin/pip install -U .[test,websupport] - - run: make test PYTHON=/python3.4/bin/python + - run: /python3.5/bin/pip install -U pip setuptools + - run: /python3.5/bin/pip install -U .[test,websupport] + - run: make test PYTHON=/python3.5/bin/python diff --git a/CHANGES b/CHANGES index 64ce91daa..87879d4bb 100644 --- a/CHANGES +++ b/CHANGES @@ -289,6 +289,10 @@ Features added Bugs fixed ---------- +* #5320: intersphinx: crashed if invalid url given +* #5326: manpage: crashed when invalid docname is specified as ``man_pages`` +* #5322: autodoc: ``Any`` typehint causes formatting error + Testing -------- diff --git a/sphinx/builders/manpage.py b/sphinx/builders/manpage.py index 32bd9950b..25287f2be 100644 --- a/sphinx/builders/manpage.py +++ b/sphinx/builders/manpage.py @@ -73,6 +73,10 @@ class ManualPageBuilder(Builder): for info in self.config.man_pages: docname, name, description, authors, section = info + if docname not in self.env.all_docs: + logger.warning(__('"man_pages" config value references unknown ' + 'document %s'), docname) + continue if isinstance(authors, string_types): if authors: authors = [authors] diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index af219d16a..5cbe4ff66 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -410,14 +410,19 @@ def inspect_main(argv): # type: (unicode) -> None print(msg, file=sys.stderr) - filename = argv[0] - invdata = fetch_inventory(MockApp(), '', filename) # type: ignore - for key in sorted(invdata or {}): - print(key) - for entry, einfo in sorted(invdata[key].items()): - print('\t%-40s %s%s' % (entry, - einfo[3] != '-' and '%-40s: ' % einfo[3] or '', - einfo[2])) + try: + filename = argv[0] + invdata = fetch_inventory(MockApp(), '', filename) # type: ignore + for key in sorted(invdata or {}): + print(key) + for entry, einfo in sorted(invdata[key].items()): + print('\t%-40s %s%s' % (entry, + einfo[3] != '-' and '%-40s: ' % einfo[3] or '', + einfo[2])) + except ValueError as exc: + print(exc.args[0] % exc.args[1:]) + except Exception as exc: + print('Unknown error: %r' % exc) if __name__ == '__main__': diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index 1512a9918..f4c3461ea 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -546,8 +546,10 @@ class Signature(object): qualname = annotation.__qualname__ elif getattr(annotation, '__forward_arg__', None): qualname = annotation.__forward_arg__ - else: + elif getattr(annotation, '__origin__', None): qualname = self.format_annotation(annotation.__origin__) # ex. Union + else: + qualname = repr(annotation).replace('typing.', '') elif hasattr(annotation, '__qualname__'): qualname = '%s.%s' % (module, annotation.__qualname__) else: diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py index 78ed7f91c..99033fb6e 100644 --- a/tests/test_util_inspect.py +++ b/tests/test_util_inspect.py @@ -232,7 +232,7 @@ def test_Signature_partialmethod(): reason='type annotation test is available on py34 or above') def test_Signature_annotations(): from typing_test_data import ( - f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, Node) + f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, Node) # Class annotations sig = inspect.Signature(f0).format_args() @@ -293,9 +293,16 @@ def test_Signature_annotations(): sig = inspect.Signature(f13).format_args() assert sig == '() -> Optional[str]' + # Any + sig = inspect.Signature(f14).format_args() + assert sig == '() -> Any' + # type hints by string sig = inspect.Signature(Node.children).format_args() - assert sig == '(self) -> List[typing_test_data.Node]' + if (3, 5, 0) <= sys.version_info < (3, 5, 3): + assert sig == '(self) -> List[Node]' + else: + assert sig == '(self) -> List[typing_test_data.Node]' sig = inspect.Signature(Node.__init__).format_args() assert sig == '(self, parent: Optional[Node]) -> None' diff --git a/tests/typing_test_data.py b/tests/typing_test_data.py index 5b161eac4..4dc2d06f5 100644 --- a/tests/typing_test_data.py +++ b/tests/typing_test_data.py @@ -1,5 +1,5 @@ from numbers import Integral -from typing import List, TypeVar, Union, Callable, Tuple, Optional +from typing import Any, List, TypeVar, Union, Callable, Tuple, Optional def f0(x: int, y: Integral) -> None: @@ -72,6 +72,10 @@ def f13() -> Optional[str]: pass +def f14() -> Any: + pass + + class Node: def __init__(self, parent: Optional['Node']) -> None: pass