mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix #2394: Sphinx crashes when html_last_updated_fmt is invalid
This commit is contained in:
1
CHANGES
1
CHANGES
@@ -16,6 +16,7 @@ Bugs fixed
|
|||||||
* C++, added support for ``extern`` and ``thread_local``.
|
* C++, added support for ``extern`` and ``thread_local``.
|
||||||
* C++, type declarations are now using the prefixes ``typedef``, ``using``, and ``type``,
|
* C++, type declarations are now using the prefixes ``typedef``, ``using``, and ``type``,
|
||||||
depending on the style of declaration.
|
depending on the style of declaration.
|
||||||
|
* #2394: Fix Sphinx crashes when html_last_updated_fmt is invalid
|
||||||
|
|
||||||
|
|
||||||
Release 1.4 (released Mar 28, 2016)
|
Release 1.4 (released Mar 28, 2016)
|
||||||
|
|||||||
@@ -530,7 +530,8 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
metadata['copyright'] = self.esc(self.config.epub_copyright)
|
metadata['copyright'] = self.esc(self.config.epub_copyright)
|
||||||
metadata['scheme'] = self.esc(self.config.epub_scheme)
|
metadata['scheme'] = self.esc(self.config.epub_scheme)
|
||||||
metadata['id'] = self.esc(self.config.epub_identifier)
|
metadata['id'] = self.esc(self.config.epub_identifier)
|
||||||
metadata['date'] = self.esc(format_date('YYYY-MM-dd', language=self.config.language))
|
metadata['date'] = self.esc(format_date('YYYY-MM-dd', language=self.config.language,
|
||||||
|
warn=self.warn))
|
||||||
metadata['files'] = files
|
metadata['files'] = files
|
||||||
metadata['spine'] = spine
|
metadata['spine'] = spine
|
||||||
metadata['guide'] = guide
|
metadata['guide'] = guide
|
||||||
|
|||||||
@@ -293,7 +293,8 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
lufmt = self.config.html_last_updated_fmt
|
lufmt = self.config.html_last_updated_fmt
|
||||||
if lufmt is not None:
|
if lufmt is not None:
|
||||||
self.last_updated = format_date(lufmt or _('MMM dd, YYYY'),
|
self.last_updated = format_date(lufmt or _('MMM dd, YYYY'),
|
||||||
language=self.config.language)
|
language=self.config.language,
|
||||||
|
warn=self.warn)
|
||||||
else:
|
else:
|
||||||
self.last_updated = None
|
self.last_updated = None
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class DefaultSubstitutions(Transform):
|
|||||||
default_priority = 210
|
default_priority = 210
|
||||||
|
|
||||||
def apply(self):
|
def apply(self):
|
||||||
|
env = self.document.settings.env
|
||||||
config = self.document.settings.env.config
|
config = self.document.settings.env.config
|
||||||
# only handle those not otherwise defined in the document
|
# only handle those not otherwise defined in the document
|
||||||
to_handle = default_substitutions - set(self.document.substitution_defs)
|
to_handle = default_substitutions - set(self.document.substitution_defs)
|
||||||
@@ -54,7 +55,7 @@ class DefaultSubstitutions(Transform):
|
|||||||
if refname == 'today' and not text:
|
if refname == 'today' and not text:
|
||||||
# special handling: can also specify a strftime format
|
# special handling: can also specify a strftime format
|
||||||
text = format_date(config.today_fmt or _('MMMM dd, YYYY'),
|
text = format_date(config.today_fmt or _('MMMM dd, YYYY'),
|
||||||
language=config.language)
|
language=config.language, warn=env.warn)
|
||||||
ref.replace_self(nodes.Text(text, text))
|
ref.replace_self(nodes.Text(text, text))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ date_format_mappings = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def babel_format_date(date, format, locale):
|
def babel_format_date(date, format, locale, warn=None):
|
||||||
if locale is None:
|
if locale is None:
|
||||||
locale = 'en'
|
locale = 'en'
|
||||||
|
|
||||||
@@ -158,9 +158,15 @@ def babel_format_date(date, format, locale):
|
|||||||
except (ValueError, babel.core.UnknownLocaleError):
|
except (ValueError, babel.core.UnknownLocaleError):
|
||||||
# fallback to English
|
# fallback to English
|
||||||
return babel.dates.format_date(date, format, locale='en')
|
return babel.dates.format_date(date, format, locale='en')
|
||||||
|
except AttributeError:
|
||||||
|
if warn:
|
||||||
|
warn('Invalid date format. Quote the string by single quote '
|
||||||
|
'if you want to output it directly: %s' % format)
|
||||||
|
|
||||||
|
return format
|
||||||
|
|
||||||
|
|
||||||
def format_date(format, date=None, language=None):
|
def format_date(format, date=None, language=None, warn=None):
|
||||||
if format is None:
|
if format is None:
|
||||||
format = 'medium'
|
format = 'medium'
|
||||||
|
|
||||||
@@ -175,7 +181,7 @@ def format_date(format, date=None, language=None):
|
|||||||
|
|
||||||
if '%' not in format:
|
if '%' not in format:
|
||||||
# consider the format as babel's
|
# consider the format as babel's
|
||||||
return babel_format_date(date, format, locale=language)
|
return babel_format_date(date, format, locale=language, warn=warn)
|
||||||
else:
|
else:
|
||||||
warnings.warn('ustrftime format support will be dropped at Sphinx-1.5',
|
warnings.warn('ustrftime format support will be dropped at Sphinx-1.5',
|
||||||
DeprecationWarning)
|
DeprecationWarning)
|
||||||
|
|||||||
@@ -185,6 +185,14 @@ def test_format_date():
|
|||||||
assert i18n.format_date(format, date=date, language='ja') == u'2月 07, 2016'
|
assert i18n.format_date(format, date=date, language='ja') == u'2月 07, 2016'
|
||||||
assert i18n.format_date(format, date=date, language='de') == 'Februar 07, 2016'
|
assert i18n.format_date(format, date=date, language='de') == 'Februar 07, 2016'
|
||||||
|
|
||||||
|
# invalid date format
|
||||||
|
format = 'Mon Mar 28 12:37:08 2016, commit 4367aef'
|
||||||
|
assert i18n.format_date(format, date=date) == format
|
||||||
|
|
||||||
|
# quoted format
|
||||||
|
quoted_format = "'Mon Mar 28 12:37:08 2016, commit 4367aef'"
|
||||||
|
assert i18n.format_date(quoted_format, date=date) == format
|
||||||
|
|
||||||
|
|
||||||
def test_get_filename_for_language():
|
def test_get_filename_for_language():
|
||||||
app = TestApp()
|
app = TestApp()
|
||||||
|
|||||||
Reference in New Issue
Block a user