Merge pull request #5400 from tk0miya/5399_find_catalog_crashes

Fix #5399: Sphinx crashes if unknown po file exists
This commit is contained in:
Takeshi KOMIYA 2018-09-09 18:38:21 +09:00 committed by GitHub
commit 578adb887f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 18 additions and 12 deletions

View File

@ -17,6 +17,8 @@ Deprecated
* ``sphinx.io.SphinxI18nReader.set_lineno_for_reporter()`` is deprecated
* ``sphinx.io.SphinxI18nReader.line`` is deprecated
* ``sphinx.util.i18n.find_catalog_source_file()`` has changed; the
*gettext_compact* argument has been deprecated
Features added
--------------
@ -41,6 +43,7 @@ Bugs fixed
* #2720, #4034: Incorrect links with ``:download:``, duplicate names, and
parallel builds
* #5290: autodoc: failed to analyze source code in egg package
* #5399: Sphinx crashes if unknown po file exists
Testing
--------

View File

@ -136,6 +136,12 @@ The following is a list of deprecated interface.
- 4.0
- :confval:`autodoc_default_options`
* - ``gettext_compact`` arguments of
``sphinx.util.i18n.find_catalog_source_files()``
- 1.8
- 3.0
- N/A
* - ``sphinx.io.SphinxI18nReader.set_lineno_for_reporter()``
- 1.8
- 3.0

View File

@ -261,7 +261,6 @@ class Builder(object):
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
self.config.language,
charset=self.config.source_encoding,
gettext_compact=self.config.gettext_compact,
force_all=True,
excluded=Matcher(['**/.?**']))
message = __('all of %d po files') % len(catalogs)
@ -284,7 +283,6 @@ class Builder(object):
self.config.language,
domains=list(specified_domains),
charset=self.config.source_encoding,
gettext_compact=self.config.gettext_compact,
excluded=Matcher(['**/.?**']))
message = __('targets for %d po files that are specified') % len(catalogs)
self.compile_catalogs(catalogs, message)
@ -295,7 +293,6 @@ class Builder(object):
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
self.config.language,
charset=self.config.source_encoding,
gettext_compact=self.config.gettext_compact,
excluded=Matcher(['**/.?**']))
message = __('targets for %d po files that are out of date') % len(catalogs)
self.compile_catalogs(catalogs, message)

View File

@ -12,6 +12,7 @@ import gettext
import io
import os
import re
import warnings
from collections import namedtuple
from datetime import datetime
from os import path
@ -20,6 +21,7 @@ import babel.dates
from babel.messages.mofile import write_mo
from babel.messages.pofile import read_po
from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.errors import SphinxError
from sphinx.locale import __
from sphinx.util import logging
@ -103,7 +105,7 @@ def find_catalog_files(docname, srcdir, locale_dirs, lang, compaction):
return files # type: ignore
def find_catalog_source_files(locale_dirs, locale, domains=None, gettext_compact=False,
def find_catalog_source_files(locale_dirs, locale, domains=None, gettext_compact=None,
charset='utf-8', force_all=False,
excluded=Matcher([])):
# type: (List[unicode], unicode, List[unicode], bool, unicode, bool, Matcher) -> Set[CatalogInfo] # NOQA
@ -115,14 +117,15 @@ def find_catalog_source_files(locale_dirs, locale, domains=None, gettext_compact
:param str locale: a language as `'en'`
:param list domains: list of domain names to get. If empty list or None
is specified, get all domain names. default is None.
:param boolean gettext_compact:
* False: keep domains directory structure (default).
* True: domains in the sub directory will be merged into 1 file.
:param boolean force_all:
Set True if you want to get all catalogs rather than updated catalogs.
default is False.
:return: [CatalogInfo(), ...]
"""
if gettext_compact is not None:
warnings.warn('gettext_compact argument for find_catalog_source_files() '
'is deprecated.', RemovedInSphinx30Warning)
catalogs = set() # type: Set[CatalogInfo]
if not locale:
@ -143,10 +146,7 @@ def find_catalog_source_files(locale_dirs, locale, domains=None, gettext_compact
if excluded(path.join(relpath(dirpath, base_dir), filename)):
continue
base = path.splitext(filename)[0]
domain = relpath(path.join(dirpath, base), base_dir)
if gettext_compact and path.sep in domain:
domain = path.split(domain)[0]
domain = domain.replace(path.sep, SEP)
domain = relpath(path.join(dirpath, base), base_dir).replace(path.sep, SEP)
if domains and domain not in domains:
continue
cat = CatalogInfo(base_dir, domain, charset)

View File

@ -154,7 +154,7 @@ def test_get_catalogs_with_compact(tempdir):
catalogs = i18n.find_catalog_source_files([tempdir / 'loc1'], 'xx', gettext_compact=True)
domains = set(c.domain for c in catalogs)
assert domains == set(['test1', 'test2', 'sub'])
assert domains == set(['test1', 'test2', 'sub/test3', 'sub/test4'])
def test_get_catalogs_excluded(tempdir):