Fix #2394: Sphinx crashes when html_last_updated_fmt is invalid

This commit is contained in:
Takeshi KOMIYA
2016-04-01 11:20:30 +09:00
parent 42395a177a
commit 8ab06530be
6 changed files with 24 additions and 6 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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))

View File

@@ -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)

View File

@@ -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()