mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fixed #1796: On py3, automated .mo building cause UnicodeDecodeError.
This commit is contained in:
1
CHANGES
1
CHANGES
@@ -33,6 +33,7 @@ Bugs fixed
|
|||||||
* #1949: Use ``safe_getattr`` in the coverage builder to avoid aborting with
|
* #1949: Use ``safe_getattr`` in the coverage builder to avoid aborting with
|
||||||
descriptors that have custom behavior.
|
descriptors that have custom behavior.
|
||||||
* #1915: Do not generate smart quotes in doc field type annotations.
|
* #1915: Do not generate smart quotes in doc field type annotations.
|
||||||
|
* #1796, On py3, automated .mo building cause UnicodeDecodeError
|
||||||
|
|
||||||
|
|
||||||
Release 1.3.1 (released Mar 17, 2015)
|
Release 1.3.1 (released Mar 17, 2015)
|
||||||
|
|||||||
@@ -200,7 +200,8 @@ class Sphinx(object):
|
|||||||
else:
|
else:
|
||||||
locale_dirs = []
|
locale_dirs = []
|
||||||
self.translator, has_translation = locale.init(locale_dirs,
|
self.translator, has_translation = locale.init(locale_dirs,
|
||||||
self.config.language)
|
self.config.language,
|
||||||
|
charset=self.config.source_encoding)
|
||||||
if self.config.language is not None:
|
if self.config.language is not None:
|
||||||
if has_translation or self.config.language == 'en':
|
if has_translation or self.config.language == 'en':
|
||||||
# "en" never needs to be translated
|
# "en" never needs to be translated
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ class Builder(object):
|
|||||||
catalogs = i18n.find_catalog_source_files(
|
catalogs = i18n.find_catalog_source_files(
|
||||||
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
|
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
|
||||||
self.config.language,
|
self.config.language,
|
||||||
|
charset=self.config.source_encoding,
|
||||||
gettext_compact=self.config.gettext_compact,
|
gettext_compact=self.config.gettext_compact,
|
||||||
force_all=True)
|
force_all=True)
|
||||||
message = 'all of %d po files' % len(catalogs)
|
message = 'all of %d po files' % len(catalogs)
|
||||||
@@ -186,6 +187,7 @@ class Builder(object):
|
|||||||
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
|
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
|
||||||
self.config.language,
|
self.config.language,
|
||||||
domains=list(specified_domains),
|
domains=list(specified_domains),
|
||||||
|
charset=self.config.source_encoding,
|
||||||
gettext_compact=self.config.gettext_compact)
|
gettext_compact=self.config.gettext_compact)
|
||||||
message = 'targets for %d po files that are specified' % len(catalogs)
|
message = 'targets for %d po files that are specified' % len(catalogs)
|
||||||
self.compile_catalogs(catalogs, message)
|
self.compile_catalogs(catalogs, message)
|
||||||
@@ -194,6 +196,7 @@ class Builder(object):
|
|||||||
catalogs = i18n.find_catalog_source_files(
|
catalogs = i18n.find_catalog_source_files(
|
||||||
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
|
[path.join(self.srcdir, x) for x in self.config.locale_dirs],
|
||||||
self.config.language,
|
self.config.language,
|
||||||
|
charset=self.config.source_encoding,
|
||||||
gettext_compact=self.config.gettext_compact)
|
gettext_compact=self.config.gettext_compact)
|
||||||
message = 'targets for %d po files that are out of date' % len(catalogs)
|
message = 'targets for %d po files that are out of date' % len(catalogs)
|
||||||
self.compile_catalogs(catalogs, message)
|
self.compile_catalogs(catalogs, message)
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ else:
|
|||||||
return translators['sphinx'].ugettext(message)
|
return translators['sphinx'].ugettext(message)
|
||||||
|
|
||||||
|
|
||||||
def init(locale_dirs, language, catalog='sphinx'):
|
def init(locale_dirs, language, catalog='sphinx', charset='utf-8'):
|
||||||
"""Look for message catalogs in `locale_dirs` and *ensure* that there is at
|
"""Look for message catalogs in `locale_dirs` and *ensure* that there is at
|
||||||
least a NullTranslations catalog set in `translators`. If called multiple
|
least a NullTranslations catalog set in `translators`. If called multiple
|
||||||
times or if several ``.mo`` files are found, their contents are merged
|
times or if several ``.mo`` files are found, their contents are merged
|
||||||
@@ -212,7 +212,8 @@ def init(locale_dirs, language, catalog='sphinx'):
|
|||||||
# compile mo files if po file is updated
|
# compile mo files if po file is updated
|
||||||
# TODO: remove circular importing
|
# TODO: remove circular importing
|
||||||
from sphinx.util.i18n import find_catalog_source_files
|
from sphinx.util.i18n import find_catalog_source_files
|
||||||
for catinfo in find_catalog_source_files(locale_dirs, language, domains=[catalog]):
|
for catinfo in find_catalog_source_files(locale_dirs, language, domains=[catalog],
|
||||||
|
charset=charset):
|
||||||
catinfo.write_mo(language)
|
catinfo.write_mo(language)
|
||||||
|
|
||||||
# loading
|
# loading
|
||||||
|
|||||||
@@ -225,7 +225,8 @@ class Locale(Transform):
|
|||||||
dirs = [path.join(env.srcdir, directory)
|
dirs = [path.join(env.srcdir, directory)
|
||||||
for directory in env.config.locale_dirs]
|
for directory in env.config.locale_dirs]
|
||||||
catalog, has_catalog = init_locale(dirs, env.config.language,
|
catalog, has_catalog = init_locale(dirs, env.config.language,
|
||||||
textdomain)
|
textdomain,
|
||||||
|
charset=env.config.source_encoding)
|
||||||
if not has_catalog:
|
if not has_catalog:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
import gettext
|
import gettext
|
||||||
|
import io
|
||||||
from os import path
|
from os import path
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ from sphinx.util.osutil import walk
|
|||||||
from sphinx.util import SEP
|
from sphinx.util import SEP
|
||||||
|
|
||||||
|
|
||||||
LocaleFileInfoBase = namedtuple('CatalogInfo', 'base_dir,domain')
|
LocaleFileInfoBase = namedtuple('CatalogInfo', 'base_dir,domain,charset')
|
||||||
|
|
||||||
|
|
||||||
class CatalogInfo(LocaleFileInfoBase):
|
class CatalogInfo(LocaleFileInfoBase):
|
||||||
@@ -46,8 +47,8 @@ class CatalogInfo(LocaleFileInfoBase):
|
|||||||
path.getmtime(self.mo_path) < path.getmtime(self.po_path))
|
path.getmtime(self.mo_path) < path.getmtime(self.po_path))
|
||||||
|
|
||||||
def write_mo(self, locale):
|
def write_mo(self, locale):
|
||||||
with open(self.po_path, 'rt') as po:
|
with io.open(self.po_path, 'rt', encoding=self.charset) as po:
|
||||||
with open(self.mo_path, 'wb') as mo:
|
with io.open(self.mo_path, 'wb') as mo:
|
||||||
write_mo(mo, read_po(po, locale))
|
write_mo(mo, read_po(po, locale))
|
||||||
|
|
||||||
|
|
||||||
@@ -72,7 +73,7 @@ def find_catalog_files(docname, srcdir, locale_dirs, lang, compaction):
|
|||||||
|
|
||||||
|
|
||||||
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=False,
|
||||||
force_all=False):
|
charset='utf-8', force_all=False):
|
||||||
"""
|
"""
|
||||||
:param list locale_dirs:
|
:param list locale_dirs:
|
||||||
list of path as `['locale_dir1', 'locale_dir2', ...]` to find
|
list of path as `['locale_dir1', 'locale_dir2', ...]` to find
|
||||||
@@ -112,7 +113,7 @@ def find_catalog_source_files(locale_dirs, locale, domains=None, gettext_compact
|
|||||||
domain = domain.replace(path.sep, SEP)
|
domain = domain.replace(path.sep, SEP)
|
||||||
if domains and domain not in domains:
|
if domains and domain not in domains:
|
||||||
continue
|
continue
|
||||||
cat = CatalogInfo(base_dir, domain)
|
cat = CatalogInfo(base_dir, domain, charset)
|
||||||
if force_all or cat.is_outdated():
|
if force_all or cat.is_outdated():
|
||||||
catalogs.add(cat)
|
catalogs.add(cat)
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from util import with_tempdir
|
|||||||
|
|
||||||
|
|
||||||
def test_catalog_info_for_file_and_path():
|
def test_catalog_info_for_file_and_path():
|
||||||
cat = i18n.CatalogInfo('path', 'domain')
|
cat = i18n.CatalogInfo('path', 'domain', 'utf-8')
|
||||||
assert cat.po_file == 'domain.po'
|
assert cat.po_file == 'domain.po'
|
||||||
assert cat.mo_file == 'domain.mo'
|
assert cat.mo_file == 'domain.mo'
|
||||||
assert cat.po_path == path.join('path', 'domain.po')
|
assert cat.po_path == path.join('path', 'domain.po')
|
||||||
@@ -28,7 +28,7 @@ def test_catalog_info_for_file_and_path():
|
|||||||
|
|
||||||
|
|
||||||
def test_catalog_info_for_sub_domain_file_and_path():
|
def test_catalog_info_for_sub_domain_file_and_path():
|
||||||
cat = i18n.CatalogInfo('path', 'sub/domain')
|
cat = i18n.CatalogInfo('path', 'sub/domain', 'utf-8')
|
||||||
assert cat.po_file == 'sub/domain.po'
|
assert cat.po_file == 'sub/domain.po'
|
||||||
assert cat.mo_file == 'sub/domain.mo'
|
assert cat.mo_file == 'sub/domain.mo'
|
||||||
assert cat.po_path == path.join('path', 'sub/domain.po')
|
assert cat.po_path == path.join('path', 'sub/domain.po')
|
||||||
@@ -38,7 +38,7 @@ def test_catalog_info_for_sub_domain_file_and_path():
|
|||||||
@with_tempdir
|
@with_tempdir
|
||||||
def test_catalog_outdated(dir):
|
def test_catalog_outdated(dir):
|
||||||
(dir / 'test.po').write_text('#')
|
(dir / 'test.po').write_text('#')
|
||||||
cat = i18n.CatalogInfo(dir, 'test')
|
cat = i18n.CatalogInfo(dir, 'test', 'utf-8')
|
||||||
assert cat.is_outdated() # if mo is not exist
|
assert cat.is_outdated() # if mo is not exist
|
||||||
|
|
||||||
mo_file = (dir / 'test.mo')
|
mo_file = (dir / 'test.mo')
|
||||||
@@ -52,7 +52,7 @@ def test_catalog_outdated(dir):
|
|||||||
@with_tempdir
|
@with_tempdir
|
||||||
def test_catalog_write_mo(dir):
|
def test_catalog_write_mo(dir):
|
||||||
(dir / 'test.po').write_text('#')
|
(dir / 'test.po').write_text('#')
|
||||||
cat = i18n.CatalogInfo(dir, 'test')
|
cat = i18n.CatalogInfo(dir, 'test', 'utf-8')
|
||||||
cat.write_mo('en')
|
cat.write_mo('en')
|
||||||
assert path.exists(cat.mo_path)
|
assert path.exists(cat.mo_path)
|
||||||
assert read_mo(open(cat.mo_path, 'rb')) is not None
|
assert read_mo(open(cat.mo_path, 'rb')) is not None
|
||||||
|
|||||||
Reference in New Issue
Block a user