mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch '1.7-release'
This commit is contained in:
commit
b924e06066
5
CHANGES
5
CHANGES
@ -54,6 +54,10 @@ Bugs fixed
|
|||||||
* #4415: autodoc classifies inherited staticmethods as regular methods
|
* #4415: autodoc classifies inherited staticmethods as regular methods
|
||||||
* #4472: DOCUMENTATION_OPTIONS is not defined
|
* #4472: DOCUMENTATION_OPTIONS is not defined
|
||||||
* #4491: autodoc: prefer _MockImporter over other importers in sys.meta_path
|
* #4491: autodoc: prefer _MockImporter over other importers in sys.meta_path
|
||||||
|
* #4490: autodoc: type annotation is broken with python 3.7.0a4+
|
||||||
|
* utils package is no longer installed
|
||||||
|
* #3952: apidoc: module header is too escaped
|
||||||
|
* #4275: Formats accepted by sphinx.util.i18n.format_date are limited
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
@ -235,6 +239,7 @@ Bugs fixed
|
|||||||
* #4434: pure numbers as link targets produce warning
|
* #4434: pure numbers as link targets produce warning
|
||||||
* #4477: Build fails after building specific files
|
* #4477: Build fails after building specific files
|
||||||
* #4449: apidoc: include "empty" packages that contain modules
|
* #4449: apidoc: include "empty" packages that contain modules
|
||||||
|
* #3917: citation labels are tranformed to ellipsis
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
|
@ -34,6 +34,12 @@ max-line-length = 95
|
|||||||
ignore = E116,E241,E251,E741
|
ignore = E116,E241,E251,E741
|
||||||
exclude = .git,.tox,.venv,tests/*,build/*,doc/_build/*,sphinx/search/*,sphinx/pycode/pgen2/*,doc/ext/example*.py
|
exclude = .git,.tox,.venv,tests/*,build/*,doc/_build/*,sphinx/search/*,sphinx/pycode/pgen2/*,doc/ext/example*.py
|
||||||
|
|
||||||
|
[flake8:local-plugins]
|
||||||
|
extension =
|
||||||
|
X101 = utils.checks:sphinx_has_header
|
||||||
|
paths =
|
||||||
|
.
|
||||||
|
|
||||||
[mypy]
|
[mypy]
|
||||||
python_version = 2.7
|
python_version = 2.7
|
||||||
show_column_numbers = True
|
show_column_numbers = True
|
||||||
|
15
setup.py
15
setup.py
@ -15,7 +15,7 @@ if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 4):
|
|||||||
print('ERROR: Sphinx requires at least Python 2.7 or 3.4 to run.')
|
print('ERROR: Sphinx requires at least Python 2.7 or 3.4 to run.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
requires = [
|
install_requires = [
|
||||||
'six>=1.5',
|
'six>=1.5',
|
||||||
'Jinja2>=2.3',
|
'Jinja2>=2.3',
|
||||||
'Pygments>=2.0',
|
'Pygments>=2.0',
|
||||||
@ -47,7 +47,7 @@ extras_require = {
|
|||||||
'pytest',
|
'pytest',
|
||||||
'pytest-cov',
|
'pytest-cov',
|
||||||
'html5lib',
|
'html5lib',
|
||||||
'flake8',
|
'flake8>=3.5.0',
|
||||||
],
|
],
|
||||||
'test:python_version<"3"': [
|
'test:python_version<"3"': [
|
||||||
'enum34',
|
'enum34',
|
||||||
@ -214,7 +214,7 @@ setup(
|
|||||||
'Topic :: Utilities',
|
'Topic :: Utilities',
|
||||||
],
|
],
|
||||||
platforms='any',
|
platforms='any',
|
||||||
packages=find_packages(exclude=['tests']),
|
packages=find_packages(exclude=['tests', 'utils']),
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
@ -226,15 +226,8 @@ setup(
|
|||||||
'distutils.commands': [
|
'distutils.commands': [
|
||||||
'build_sphinx = sphinx.setup_command:BuildDoc',
|
'build_sphinx = sphinx.setup_command:BuildDoc',
|
||||||
],
|
],
|
||||||
# consider moving this to 'flake8:local-plugins' once flake8 3.5.0 is
|
|
||||||
# in the wild:
|
|
||||||
# http://flake8.pycqa.org/en/latest/user/configuration.html\
|
|
||||||
# #using-local-plugins
|
|
||||||
'flake8.extension': [
|
|
||||||
'X101 = utils.checks:sphinx_has_header',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
install_requires=requires,
|
install_requires=install_requires,
|
||||||
extras_require=extras_require,
|
extras_require=extras_require,
|
||||||
cmdclass=cmdclass,
|
cmdclass=cmdclass,
|
||||||
)
|
)
|
||||||
|
@ -212,10 +212,15 @@ class CitationReferences(SphinxTransform):
|
|||||||
|
|
||||||
def apply(self):
|
def apply(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
|
# mark citation labels as not smartquoted
|
||||||
|
for citnode in self.document.traverse(nodes.citation):
|
||||||
|
citnode[0]['support_smartquotes'] = False
|
||||||
|
|
||||||
for citnode in self.document.traverse(nodes.citation_reference):
|
for citnode in self.document.traverse(nodes.citation_reference):
|
||||||
cittext = citnode.astext()
|
cittext = citnode.astext()
|
||||||
refnode = addnodes.pending_xref(cittext, refdomain='std', reftype='citation',
|
refnode = addnodes.pending_xref(cittext, refdomain='std', reftype='citation',
|
||||||
reftarget=cittext, refwarn=True,
|
reftarget=cittext, refwarn=True,
|
||||||
|
support_smartquotes=False,
|
||||||
ids=citnode["ids"])
|
ids=citnode["ids"])
|
||||||
refnode.source = citnode.source or citnode.parent.source
|
refnode.source = citnode.source or citnode.parent.source
|
||||||
refnode.line = citnode.line or citnode.parent.line
|
refnode.line = citnode.line or citnode.parent.line
|
||||||
|
@ -157,21 +157,30 @@ date_format_mappings = {
|
|||||||
'%b': 'MMM', # Month as locale’s abbreviated name.
|
'%b': 'MMM', # Month as locale’s abbreviated name.
|
||||||
'%B': 'MMMM', # Month as locale’s full name.
|
'%B': 'MMMM', # Month as locale’s full name.
|
||||||
'%c': 'medium', # Locale’s appropriate date and time representation.
|
'%c': 'medium', # Locale’s appropriate date and time representation.
|
||||||
|
'%-d': 'd', # Day of the month as a decimal number.
|
||||||
'%d': 'dd', # Day of the month as a zero-padded decimal number.
|
'%d': 'dd', # Day of the month as a zero-padded decimal number.
|
||||||
'%H': 'HH', # Hour (24-hour clock) as a decimal number [00,23].
|
'%-H': 'H', # Hour (24-hour clock) as a decimal number [0,23].
|
||||||
'%I': 'hh', # Hour (12-hour clock) as a decimal number [01,12].
|
'%H': 'HH', # Hour (24-hour clock) as a zero-padded decimal number [00,23].
|
||||||
|
'%-I': 'h', # Hour (12-hour clock) as a decimal number [1,12].
|
||||||
|
'%I': 'hh', # Hour (12-hour clock) as a zero-padded decimal number [01,12].
|
||||||
|
'%-j': 'D', # Day of the year as a decimal number.
|
||||||
'%j': 'DDD', # Day of the year as a zero-padded decimal number.
|
'%j': 'DDD', # Day of the year as a zero-padded decimal number.
|
||||||
|
'%-m': 'M', # Month as a decimal number.
|
||||||
'%m': 'MM', # Month as a zero-padded decimal number.
|
'%m': 'MM', # Month as a zero-padded decimal number.
|
||||||
'%M': 'mm', # Minute as a decimal number [00,59].
|
'%-M': 'm', # Minute as a decimal number [0,59].
|
||||||
|
'%M': 'mm', # Minute as a zero-padded decimal number [00,59].
|
||||||
'%p': 'a', # Locale’s equivalent of either AM or PM.
|
'%p': 'a', # Locale’s equivalent of either AM or PM.
|
||||||
'%S': 'ss', # Second as a decimal number.
|
'%-S': 's', # Second as a decimal number.
|
||||||
|
'%S': 'ss', # Second as a zero-padded decimal number.
|
||||||
'%U': 'WW', # Week number of the year (Sunday as the first day of the week)
|
'%U': 'WW', # Week number of the year (Sunday as the first day of the week)
|
||||||
# as a zero padded decimal number. All days in a new year preceding
|
# as a zero padded decimal number. All days in a new year preceding
|
||||||
# the first Sunday are considered to be in week 0.
|
# the first Sunday are considered to be in week 0.
|
||||||
'%w': 'e', # Weekday as a decimal number, where 0 is Sunday and 6 is Saturday.
|
'%w': 'e', # Weekday as a decimal number, where 0 is Sunday and 6 is Saturday.
|
||||||
'%W': 'WW', # Week number of the year (Monday as the first day of the week)
|
'%-W': 'W', # Week number of the year (Monday as the first day of the week)
|
||||||
# as a decimal number. All days in a new year preceding the first
|
# as a decimal number. All days in a new year preceding the first
|
||||||
# Monday are considered to be in week 0.
|
# Monday are considered to be in week 0.
|
||||||
|
'%W': 'WW', # Week number of the year (Monday as the first day of the week)
|
||||||
|
# as a zero-padded decimal number.
|
||||||
'%x': 'medium', # Locale’s appropriate date representation.
|
'%x': 'medium', # Locale’s appropriate date representation.
|
||||||
'%X': 'medium', # Locale’s appropriate time representation.
|
'%X': 'medium', # Locale’s appropriate time representation.
|
||||||
'%y': 'YY', # Year without century as a zero-padded decimal number.
|
'%y': 'YY', # Year without century as a zero-padded decimal number.
|
||||||
@ -180,6 +189,8 @@ date_format_mappings = {
|
|||||||
'%%': '%',
|
'%%': '%',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
date_format_re = re.compile('(%s)' % '|'.join(date_format_mappings))
|
||||||
|
|
||||||
|
|
||||||
def babel_format_date(date, format, locale, formatter=babel.dates.format_date):
|
def babel_format_date(date, format, locale, formatter=babel.dates.format_date):
|
||||||
# type: (datetime, unicode, unicode, Callable) -> unicode
|
# type: (datetime, unicode, unicode, Callable) -> unicode
|
||||||
@ -214,7 +225,7 @@ def format_date(format, date=None, language=None):
|
|||||||
date = datetime.now()
|
date = datetime.now()
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
tokens = re.split('(%.)', format)
|
tokens = date_format_re.split(format)
|
||||||
for token in tokens:
|
for token in tokens:
|
||||||
if token in date_format_mappings:
|
if token in date_format_mappings:
|
||||||
babel_format = date_format_mappings.get(token, '')
|
babel_format = date_format_mappings.get(token, '')
|
||||||
|
@ -431,6 +431,55 @@ class Signature(object):
|
|||||||
|
|
||||||
Displaying complex types from ``typing`` relies on its private API.
|
Displaying complex types from ``typing`` relies on its private API.
|
||||||
"""
|
"""
|
||||||
|
if sys.version_info >= (3, 7): # py37+
|
||||||
|
return self.format_annotation_new(annotation)
|
||||||
|
else:
|
||||||
|
return self.format_annotation_old(annotation)
|
||||||
|
|
||||||
|
def format_annotation_new(self, annotation):
|
||||||
|
# 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__
|
||||||
|
else:
|
||||||
|
qualname = self.format_annotation(annotation.__origin__) # ex. Union
|
||||||
|
elif hasattr(annotation, '__qualname__'):
|
||||||
|
qualname = '%s.%s' % (module, annotation.__qualname__)
|
||||||
|
else:
|
||||||
|
qualname = repr(annotation)
|
||||||
|
|
||||||
|
if getattr(annotation, '__args__', None):
|
||||||
|
if qualname == 'Union':
|
||||||
|
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])
|
||||||
|
return '%s[[%s], %s]' % (qualname, args, returns)
|
||||||
|
else:
|
||||||
|
args = ', '.join(self.format_annotation(a) for a in annotation.__args__)
|
||||||
|
return '%s[%s]' % (qualname, args)
|
||||||
|
|
||||||
|
return qualname
|
||||||
|
|
||||||
|
def format_annotation_old(self, annotation):
|
||||||
|
# type: (Any) -> str
|
||||||
|
"""format_annotation() for py36 or below"""
|
||||||
if isinstance(annotation, string_types):
|
if isinstance(annotation, string_types):
|
||||||
return annotation # type: ignore
|
return annotation # type: ignore
|
||||||
if isinstance(annotation, typing.TypeVar): # type: ignore
|
if isinstance(annotation, typing.TypeVar): # type: ignore
|
||||||
|
@ -354,6 +354,8 @@ def is_smartquotable(node):
|
|||||||
"""Check the node is smart-quotable or not."""
|
"""Check the node is smart-quotable or not."""
|
||||||
if isinstance(node.parent, NON_SMARTQUOTABLE_PARENT_NODES):
|
if isinstance(node.parent, NON_SMARTQUOTABLE_PARENT_NODES):
|
||||||
return False
|
return False
|
||||||
|
elif node.parent.get('support_smartquotes', None) is False:
|
||||||
|
return False
|
||||||
elif getattr(node, 'support_smartquotes', None) is False:
|
elif getattr(node, 'support_smartquotes', None) is False:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
@ -23,13 +23,15 @@ if False:
|
|||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Generator # NOQA
|
from typing import Generator # NOQA
|
||||||
|
|
||||||
symbols_re = re.compile(r'([!-/:-@\[-`{-~])')
|
symbols_re = re.compile(r'([!--/:-@\[-`{-~])') # symbols without dot(0x2e)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def escape(text):
|
def escape(text):
|
||||||
# type: (unicode) -> unicode
|
# type: (unicode) -> unicode
|
||||||
return symbols_re.sub(r'\\\1', text) # type: ignore
|
text = symbols_re.sub(r'\\\1', text) # type: ignore
|
||||||
|
text = re.sub(r'^\.', r'\.', text) # escape a dot at top
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
|
@ -176,6 +176,8 @@ def test_format_date():
|
|||||||
datet = datetime.datetime(2016, 2, 7, 5, 11, 17, 0)
|
datet = datetime.datetime(2016, 2, 7, 5, 11, 17, 0)
|
||||||
assert i18n.format_date(format, date=datet) == 'February 07, 2016, 05:11:17 05 AM'
|
assert i18n.format_date(format, date=datet) == 'February 07, 2016, 05:11:17 05 AM'
|
||||||
|
|
||||||
|
format = '%B %-d, %Y, %-H:%-M:%-S %-I %p'
|
||||||
|
assert i18n.format_date(format, date=datet) == 'February 7, 2016, 5:11:17 5 AM'
|
||||||
format = '%x'
|
format = '%x'
|
||||||
assert i18n.format_date(format, date=datet) == 'Feb 7, 2016'
|
assert i18n.format_date(format, date=datet) == 'Feb 7, 2016'
|
||||||
format = '%X'
|
format = '%X'
|
||||||
|
@ -215,12 +215,7 @@ def test_Signature_annotations():
|
|||||||
|
|
||||||
# TypeVars and generic types with TypeVars
|
# TypeVars and generic types with TypeVars
|
||||||
sig = inspect.Signature(f2).format_args()
|
sig = inspect.Signature(f2).format_args()
|
||||||
if sys.version_info < (3, 7):
|
assert sig == '(x: List[T], y: List[T_co], z: T) -> List[T_contra]'
|
||||||
sig == ('(x: typing.List[T], y: typing.List[T_co], z: T) -> '
|
|
||||||
'typing.List[T_contra]')
|
|
||||||
else:
|
|
||||||
sig == ('(x: typing.List[~T], y: typing.List[+T_co], z: T) -> '
|
|
||||||
'typing.List[-T_contra]')
|
|
||||||
|
|
||||||
# Union types
|
# Union types
|
||||||
sig = inspect.Signature(f3).format_args()
|
sig = inspect.Signature(f3).format_args()
|
||||||
|
@ -14,3 +14,5 @@ from sphinx.util.rst import escape
|
|||||||
def test_escape():
|
def test_escape():
|
||||||
assert escape(':ref:`id`') == r'\:ref\:\`id\`'
|
assert escape(':ref:`id`') == r'\:ref\:\`id\`'
|
||||||
assert escape('footnote [#]_') == r'footnote \[\#\]\_'
|
assert escape('footnote [#]_') == r'footnote \[\#\]\_'
|
||||||
|
assert escape('sphinx.application') == r'sphinx.application'
|
||||||
|
assert escape('.. toctree::') == r'\.. toctree\:\:'
|
||||||
|
Loading…
Reference in New Issue
Block a user