mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2026-10-25 14:40:22 -05:00
Merge branch '1.7'
This commit is contained in:
commit
11331c5923
5 files changed
+92
-52
No files matched your search
@@ -258,6 +258,10 @@ Bugs fixed
|
||||
1.5
|
||||
* LaTeX: fix the :confval:`latex_engine` documentation regarding Latin Modern
|
||||
font with XeLaTeX/LuaLateX (refs: #5251)
|
||||
* #5280: autodoc: Fix wrong type annotations for complex typing
|
||||
* autodoc: Optional types are wrongly rendered
|
||||
* #5291: autodoc crashed by ForwardRef types
|
||||
* #5298: imgmath: math_number_all causes equations to have two numbers in html
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
||||
@@ -318,8 +318,7 @@ def html_visit_displaymath(self, node):
|
||||
if node['nowrap']:
|
||||
latex = node.astext()
|
||||
else:
|
||||
latex = wrap_displaymath(node.astext(), None,
|
||||
self.builder.config.math_number_all)
|
||||
latex = wrap_displaymath(node.astext(), None, False)
|
||||
try:
|
||||
fname, depth = render_math(self, latex)
|
||||
except MathExtError as exc:
|
||||
|
||||
+59
-46
@@ -20,6 +20,7 @@ from six import PY2, PY3, StringIO, binary_type, string_types, itervalues
|
||||
from six.moves import builtins
|
||||
|
||||
from sphinx.util import force_decode
|
||||
from sphinx.util.pycompat import NoneType
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
@@ -444,8 +445,7 @@ class Signature(object):
|
||||
if PY2 or self.return_annotation is inspect.Parameter.empty:
|
||||
return '(%s)' % ', '.join(args)
|
||||
else:
|
||||
if isinstance(self.return_annotation, string_types) and \
|
||||
'return' in self.annotations:
|
||||
if 'return' in self.annotations:
|
||||
annotation = self.format_annotation(self.annotations['return'])
|
||||
else:
|
||||
annotation = self.format_annotation(self.return_annotation)
|
||||
@@ -461,6 +461,19 @@ class Signature(object):
|
||||
|
||||
Displaying complex types from ``typing`` relies on its private API.
|
||||
"""
|
||||
if isinstance(annotation, string_types):
|
||||
return annotation # type: ignore
|
||||
elif isinstance(annotation, typing.TypeVar): # type: ignore
|
||||
return annotation.__name__
|
||||
elif not annotation:
|
||||
return repr(annotation)
|
||||
elif annotation is NoneType: # type: ignore
|
||||
return 'None'
|
||||
elif getattr(annotation, '__module__', None) == 'builtins':
|
||||
return annotation.__qualname__
|
||||
elif annotation is Ellipsis:
|
||||
return '...'
|
||||
|
||||
if sys.version_info >= (3, 7): # py37+
|
||||
return self.format_annotation_new(annotation)
|
||||
else:
|
||||
@@ -470,22 +483,13 @@ class Signature(object):
|
||||
# type: (Any) -> str
|
||||
"""format_annotation() for py37+"""
|
||||
module = getattr(annotation, '__module__', None)
|
||||
if isinstance(annotation, string_types):
|
||||
return annotation # type: ignore
|
||||
elif isinstance(annotation, typing.TypeVar): # type: ignore
|
||||
return annotation.__name__
|
||||
elif not annotation:
|
||||
return repr(annotation)
|
||||
elif module == 'builtins':
|
||||
return annotation.__qualname__
|
||||
elif annotation is Ellipsis:
|
||||
return '...'
|
||||
|
||||
if module == 'typing':
|
||||
if getattr(annotation, '_name', None):
|
||||
qualname = annotation._name
|
||||
elif getattr(annotation, '__qualname__', None):
|
||||
qualname = annotation.__qualname__
|
||||
elif getattr(annotation, '__forward_arg__', None):
|
||||
qualname = annotation.__forward_arg__
|
||||
else:
|
||||
qualname = self.format_annotation(annotation.__origin__) # ex. Union
|
||||
elif hasattr(annotation, '__qualname__'):
|
||||
@@ -495,8 +499,11 @@ class Signature(object):
|
||||
|
||||
if getattr(annotation, '__args__', None):
|
||||
if qualname == 'Union':
|
||||
args = ', '.join(self.format_annotation(a) for a in annotation.__args__)
|
||||
return '%s[%s]' % (qualname, args)
|
||||
if len(annotation.__args__) == 2 and annotation.__args__[1] is NoneType: # type: ignore # NOQA
|
||||
return 'Optional[%s]' % self.format_annotation(annotation.__args__[0])
|
||||
else:
|
||||
args = ', '.join(self.format_annotation(a) for a in annotation.__args__)
|
||||
return '%s[%s]' % (qualname, args)
|
||||
elif qualname == 'Callable':
|
||||
args = ', '.join(self.format_annotation(a) for a in annotation.__args__[:-1])
|
||||
returns = self.format_annotation(annotation.__args__[-1])
|
||||
@@ -510,35 +517,28 @@ class Signature(object):
|
||||
def format_annotation_old(self, annotation):
|
||||
# type: (Any) -> str
|
||||
"""format_annotation() for py36 or below"""
|
||||
if isinstance(annotation, string_types):
|
||||
return annotation # type: ignore
|
||||
if isinstance(annotation, typing.TypeVar): # type: ignore
|
||||
return annotation.__name__
|
||||
if annotation == Ellipsis:
|
||||
return '...'
|
||||
if not isinstance(annotation, type):
|
||||
qualified_name = repr(annotation)
|
||||
if qualified_name.startswith('typing.'): # for typing.Union
|
||||
return qualified_name.split('.', 1)[1]
|
||||
module = getattr(annotation, '__module__', None)
|
||||
if module == 'typing':
|
||||
if getattr(annotation, '_name', None):
|
||||
qualname = annotation._name
|
||||
elif getattr(annotation, '__qualname__', None):
|
||||
qualname = annotation.__qualname__
|
||||
elif getattr(annotation, '__forward_arg__', None):
|
||||
qualname = annotation.__forward_arg__
|
||||
else:
|
||||
return qualified_name
|
||||
|
||||
if not annotation:
|
||||
qualified_name = repr(annotation)
|
||||
elif annotation.__module__ == 'typing':
|
||||
qualified_name = annotation.__qualname__ # type: ignore
|
||||
qualname = self.format_annotation(annotation.__origin__) # ex. Union
|
||||
elif hasattr(annotation, '__qualname__'):
|
||||
qualname = '%s.%s' % (module, annotation.__qualname__)
|
||||
else:
|
||||
qualified_name = (annotation.__module__ + '.' + annotation.__qualname__) # type: ignore # NOQA
|
||||
qualname = repr(annotation)
|
||||
|
||||
if annotation.__module__ == 'builtins':
|
||||
return annotation.__qualname__ # type: ignore
|
||||
elif (hasattr(typing, 'TupleMeta') and
|
||||
isinstance(annotation, typing.TupleMeta) and # type: ignore
|
||||
not hasattr(annotation, '__tuple_params__')):
|
||||
if (hasattr(typing, 'TupleMeta') and
|
||||
isinstance(annotation, typing.TupleMeta) and # type: ignore
|
||||
not hasattr(annotation, '__tuple_params__')):
|
||||
# This is for Python 3.6+, 3.5 case is handled below
|
||||
params = annotation.__args__
|
||||
param_str = ', '.join(self.format_annotation(p) for p in params)
|
||||
return '%s[%s]' % (qualified_name, param_str)
|
||||
return '%s[%s]' % (qualname, param_str)
|
||||
elif (hasattr(typing, 'GenericMeta') and # for py36 or below
|
||||
isinstance(annotation, typing.GenericMeta)):
|
||||
# In Python 3.5.2+, all arguments are stored in __args__,
|
||||
@@ -554,19 +554,32 @@ class Signature(object):
|
||||
args = ', '.join(self.format_annotation(arg) for arg
|
||||
in annotation.__args__[:-1]) # type: ignore
|
||||
result = self.format_annotation(annotation.__args__[-1]) # type: ignore
|
||||
return '%s[[%s], %s]' % (qualified_name, args, result)
|
||||
return '%s[[%s], %s]' % (qualname, args, result)
|
||||
elif hasattr(annotation, '__parameters__'):
|
||||
params = annotation.__parameters__ # type: ignore
|
||||
if params is not None:
|
||||
param_str = ', '.join(self.format_annotation(p) for p in params)
|
||||
return '%s[%s]' % (qualified_name, param_str)
|
||||
return '%s[%s]' % (qualname, param_str)
|
||||
elif (hasattr(typing, 'UnionMeta') and # for py35 or below
|
||||
isinstance(annotation, typing.UnionMeta) and # type: ignore
|
||||
hasattr(annotation, '__union_params__')):
|
||||
params = annotation.__union_params__
|
||||
if params is not None:
|
||||
param_str = ', '.join(self.format_annotation(p) for p in params)
|
||||
return '%s[%s]' % (qualified_name, param_str)
|
||||
if len(params) == 2 and params[1] is NoneType: # type: ignore
|
||||
return 'Optional[%s]' % self.format_annotation(params[0])
|
||||
else:
|
||||
param_str = ', '.join(self.format_annotation(p) for p in params)
|
||||
return '%s[%s]' % (qualname, param_str)
|
||||
elif (hasattr(typing, 'Union') and # for py36
|
||||
hasattr(annotation, '__origin__') and
|
||||
annotation.__origin__ is typing.Union):
|
||||
params = annotation.__args__
|
||||
if params is not None:
|
||||
if len(params) == 2 and params[1] is NoneType: # type: ignore
|
||||
return 'Optional[%s]' % self.format_annotation(params[0])
|
||||
else:
|
||||
param_str = ', '.join(self.format_annotation(p) for p in params)
|
||||
return 'Union[%s]' % param_str
|
||||
elif (hasattr(typing, 'CallableMeta') and # for py36 or below
|
||||
isinstance(annotation, typing.CallableMeta) and # type: ignore
|
||||
getattr(annotation, '__args__', None) is not None and
|
||||
@@ -574,13 +587,13 @@ class Signature(object):
|
||||
# Skipped in the case of plain typing.Callable
|
||||
args = annotation.__args__
|
||||
if args is None:
|
||||
return qualified_name
|
||||
return qualname
|
||||
elif args is Ellipsis:
|
||||
args_str = '...'
|
||||
else:
|
||||
formatted_args = (self.format_annotation(a) for a in args)
|
||||
args_str = '[%s]' % ', '.join(formatted_args)
|
||||
return '%s[%s, %s]' % (qualified_name,
|
||||
return '%s[%s, %s]' % (qualname,
|
||||
args_str,
|
||||
self.format_annotation(annotation.__result__))
|
||||
elif (hasattr(typing, 'TupleMeta') and # for py36 or below
|
||||
@@ -592,10 +605,10 @@ class Signature(object):
|
||||
param_strings = [self.format_annotation(p) for p in params]
|
||||
if annotation.__tuple_use_ellipsis__:
|
||||
param_strings.append('...')
|
||||
return '%s[%s]' % (qualified_name,
|
||||
return '%s[%s]' % (qualname,
|
||||
', '.join(param_strings))
|
||||
|
||||
return qualified_name
|
||||
return qualname
|
||||
|
||||
|
||||
if sys.version_info >= (3, 5):
|
||||
|
||||
@@ -228,10 +228,11 @@ def test_Signature_partialmethod():
|
||||
assert sig == '()'
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 5),
|
||||
reason='type annotation test is available on py35 or above')
|
||||
@pytest.mark.skipif(sys.version_info < (3, 4),
|
||||
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
|
||||
from typing_test_data import (
|
||||
f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, Node)
|
||||
|
||||
# Class annotations
|
||||
sig = inspect.Signature(f0).format_args()
|
||||
@@ -288,6 +289,17 @@ def test_Signature_annotations():
|
||||
sig = inspect.Signature(f12).format_args()
|
||||
assert sig == '() -> Tuple[int, str, int]'
|
||||
|
||||
# optional
|
||||
sig = inspect.Signature(f13).format_args()
|
||||
assert sig == '() -> Optional[str]'
|
||||
|
||||
# type hints by string
|
||||
sig = inspect.Signature(Node.children).format_args()
|
||||
assert sig == '(self) -> List[typing_test_data.Node]'
|
||||
|
||||
sig = inspect.Signature(Node.__init__).format_args()
|
||||
assert sig == '(self, parent: Optional[Node]) -> None'
|
||||
|
||||
|
||||
def test_safe_getattr_with_default():
|
||||
class Foo(object):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from numbers import Integral
|
||||
from typing import List, TypeVar, Union, Callable, Tuple
|
||||
from typing import List, TypeVar, Union, Callable, Tuple, Optional
|
||||
|
||||
|
||||
def f0(x: int, y: Integral) -> None:
|
||||
@@ -66,3 +66,15 @@ def f11(x: CustomAnnotation(), y: 123) -> None:
|
||||
|
||||
def f12() -> Tuple[int, str, int]:
|
||||
pass
|
||||
|
||||
|
||||
def f13() -> Optional[str]:
|
||||
pass
|
||||
|
||||
|
||||
class Node:
|
||||
def __init__(self, parent: Optional['Node']) -> None:
|
||||
pass
|
||||
|
||||
def children(self) -> List['Node']:
|
||||
pass
|
||||
Reference in new issue
Block a user