Fix #3833: command line messages are translated unintentionally

This commit is contained in:
Takeshi KOMIYA 2017-06-25 17:35:42 +09:00
parent e0a1fede6d
commit 41bb5f7fd2
16 changed files with 146 additions and 133 deletions

View File

@ -38,6 +38,8 @@ Bugs fixed
* #3873: Failure of deprecation warning mechanism of * #3873: Failure of deprecation warning mechanism of
``sphinx.util.compat.Directive`` ``sphinx.util.compat.Directive``
* #3874: Bogus warnings for "citation not referenced" for cross-file citations * #3874: Bogus warnings for "citation not referenced" for cross-file citations
* #3833: command line messages are translated unintentionally with ``language``
setting.
Testing Testing
-------- --------

View File

@ -9,7 +9,7 @@ upload = upload --sign --identity=36580288
[extract_messages] [extract_messages]
mapping_file = babel.cfg mapping_file = babel.cfg
output_file = sphinx/locale/sphinx.pot output_file = sphinx/locale/sphinx.pot
keywords = _ l_ lazy_gettext keywords = _ __ l_ lazy_gettext
[update_catalog] [update_catalog]
input_file = sphinx/locale/sphinx.pot input_file = sphinx/locale/sphinx.pot

View File

@ -34,7 +34,7 @@ from sphinx.environment import BuildEnvironment
from sphinx.events import EventManager from sphinx.events import EventManager
from sphinx.extension import verify_required_extensions from sphinx.extension import verify_required_extensions
from sphinx.io import SphinxStandaloneReader from sphinx.io import SphinxStandaloneReader
from sphinx.locale import _ from sphinx.locale import __
from sphinx.registry import SphinxComponentRegistry from sphinx.registry import SphinxComponentRegistry
from sphinx.util import pycompat # noqa: F401 from sphinx.util import pycompat # noqa: F401
from sphinx.util import import_object from sphinx.util import import_object
@ -179,7 +179,7 @@ class Sphinx(object):
# check the Sphinx version if requested # check the Sphinx version if requested
if self.config.needs_sphinx and self.config.needs_sphinx > sphinx.__display_version__: if self.config.needs_sphinx and self.config.needs_sphinx > sphinx.__display_version__:
raise VersionRequirementError( raise VersionRequirementError(
_('This project needs at least Sphinx v%s and therefore cannot ' __('This project needs at least Sphinx v%s and therefore cannot '
'be built with this version.') % self.config.needs_sphinx) 'be built with this version.') % self.config.needs_sphinx)
# set confdir to srcdir if -C given (!= no confdir); a few pieces # set confdir to srcdir if -C given (!= no confdir); a few pieces
@ -206,7 +206,7 @@ class Sphinx(object):
self.config.setup(self) self.config.setup(self)
else: else:
raise ConfigError( raise ConfigError(
_("'setup' as currently defined in conf.py isn't a Python callable. " __("'setup' as currently defined in conf.py isn't a Python callable. "
"Please modify its definition to make it a callable function. This is " "Please modify its definition to make it a callable function. This is "
"needed for conf.py to behave as a Sphinx extension.") "needed for conf.py to behave as a Sphinx extension.")
) )
@ -220,7 +220,7 @@ class Sphinx(object):
# check primary_domain if requested # check primary_domain if requested
primary_domain = self.config.primary_domain primary_domain = self.config.primary_domain
if primary_domain and not self.registry.has_domain(primary_domain): if primary_domain and not self.registry.has_domain(primary_domain):
logger.warning(_('primary_domain %r not found, ignored.'), primary_domain) logger.warning(__('primary_domain %r not found, ignored.'), primary_domain)
# create the builder # create the builder
self.builder = self.create_builder(buildername) self.builder = self.create_builder(buildername)
@ -257,7 +257,7 @@ class Sphinx(object):
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
logger.info(_('done')) logger.info(__('done'))
else: else:
logger.info('not available for built-in messages') logger.info('not available for built-in messages')
@ -278,19 +278,19 @@ class Sphinx(object):
self.env.domains[domain.name] = domain self.env.domains[domain.name] = domain
else: else:
try: try:
logger.info(bold(_('loading pickled environment... ')), nonl=True) logger.info(bold(__('loading pickled environment... ')), nonl=True)
filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME) filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
self.env = BuildEnvironment.frompickle(filename, self) self.env = BuildEnvironment.frompickle(filename, self)
self.env.domains = {} self.env.domains = {}
for domain in self.registry.create_domains(self.env): for domain in self.registry.create_domains(self.env):
# this can raise if the data version doesn't fit # this can raise if the data version doesn't fit
self.env.domains[domain.name] = domain self.env.domains[domain.name] = domain
logger.info(_('done')) logger.info(__('done'))
except Exception as err: except Exception as err:
if isinstance(err, IOError) and err.errno == ENOENT: if isinstance(err, IOError) and err.errno == ENOENT:
logger.info(_('not yet created')) logger.info(__('not yet created'))
else: else:
logger.info(_('failed: %s'), err) logger.info(__('failed: %s'), err)
self._init_env(freshenv=True) self._init_env(freshenv=True)
def preload_builder(self, name): def preload_builder(self, name):
@ -300,7 +300,7 @@ class Sphinx(object):
def create_builder(self, name): def create_builder(self, name):
# type: (unicode) -> Builder # type: (unicode) -> Builder
if name is None: if name is None:
logger.info(_('No builder selected, using default: html')) logger.info(__('No builder selected, using default: html'))
name = 'html' name = 'html'
return self.registry.create_builder(self, name) return self.registry.create_builder(self, name)
@ -339,13 +339,13 @@ class Sphinx(object):
self.builder.build_update() self.builder.build_update()
status = (self.statuscode == 0 and status = (self.statuscode == 0 and
_('succeeded') or _('finished with problems')) __('succeeded') or __('finished with problems'))
if self._warncount: if self._warncount:
logger.info(bold(_('build %s, %s warning%s.') % logger.info(bold(__('build %s, %s warning%s.') %
(status, self._warncount, (status, self._warncount,
self._warncount != 1 and 's' or ''))) self._warncount != 1 and 's' or '')))
else: else:
logger.info(bold(_('build %s.') % status)) logger.info(bold(__('build %s.') % status))
except Exception as err: except Exception as err:
# delete the saved env to force a fresh build next time # delete the saved env to force a fresh build next time
envfile = path.join(self.doctreedir, ENV_PICKLE_FILENAME) envfile = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
@ -504,7 +504,7 @@ class Sphinx(object):
logger.debug('[app] adding config value: %r', logger.debug('[app] adding config value: %r',
(name, default, rebuild) + ((types,) if types else ())) # type: ignore (name, default, rebuild) + ((types,) if types else ())) # type: ignore
if name in self.config: if name in self.config:
raise ExtensionError(_('Config value %r already present') % name) raise ExtensionError(__('Config value %r already present') % name)
if rebuild in (False, True): if rebuild in (False, True):
rebuild = rebuild and 'env' or '' rebuild = rebuild and 'env' or ''
self.config.add(name, default, rebuild, types) self.config.add(name, default, rebuild, types)
@ -516,7 +516,7 @@ class Sphinx(object):
def set_translator(self, name, translator_class): def set_translator(self, name, translator_class):
# type: (unicode, Type[nodes.NodeVisitor]) -> None # type: (unicode, Type[nodes.NodeVisitor]) -> None
logger.info(bold(_('Change of translator for the %s builder.') % name)) logger.info(bold(__('Change of translator for the %s builder.') % name))
self.registry.add_translator(name, translator_class) self.registry.add_translator(name, translator_class)
def add_node(self, node, **kwds): def add_node(self, node, **kwds):
@ -524,7 +524,7 @@ class Sphinx(object):
logger.debug('[app] adding node: %r', (node, kwds)) logger.debug('[app] adding node: %r', (node, kwds))
if not kwds.pop('override', False) and \ if not kwds.pop('override', False) and \
hasattr(nodes.GenericNodeVisitor, 'visit_' + node.__name__): hasattr(nodes.GenericNodeVisitor, 'visit_' + node.__name__):
logger.warning(_('while setting up extension %s: node class %r is ' logger.warning(__('while setting up extension %s: node class %r is '
'already registered, its visitors will be overridden'), 'already registered, its visitors will be overridden'),
self._setting_up_extension, node.__name__, self._setting_up_extension, node.__name__,
type='app', subtype='add_node') type='app', subtype='add_node')
@ -533,7 +533,7 @@ class Sphinx(object):
try: try:
visit, depart = val visit, depart = val
except ValueError: except ValueError:
raise ExtensionError(_('Value for key %r must be a ' raise ExtensionError(__('Value for key %r must be a '
'(visit, depart) function tuple') % key) '(visit, depart) function tuple') % key)
translator = self.registry.translators.get(key) translator = self.registry.translators.get(key)
translators = [] translators = []
@ -580,7 +580,7 @@ class Sphinx(object):
logger.debug('[app] adding directive: %r', logger.debug('[app] adding directive: %r',
(name, obj, content, arguments, options)) (name, obj, content, arguments, options))
if name in directives._directives: if name in directives._directives:
logger.warning(_('while setting up extension %s: directive %r is ' logger.warning(__('while setting up extension %s: directive %r is '
'already registered, it will be overridden'), 'already registered, it will be overridden'),
self._setting_up_extension[-1], name, self._setting_up_extension[-1], name,
type='app', subtype='add_directive') type='app', subtype='add_directive')
@ -591,7 +591,7 @@ class Sphinx(object):
# type: (unicode, Any) -> None # type: (unicode, Any) -> None
logger.debug('[app] adding role: %r', (name, role)) logger.debug('[app] adding role: %r', (name, role))
if name in roles._roles: if name in roles._roles:
logger.warning(_('while setting up extension %s: role %r is ' logger.warning(__('while setting up extension %s: role %r is '
'already registered, it will be overridden'), 'already registered, it will be overridden'),
self._setting_up_extension[-1], name, self._setting_up_extension[-1], name,
type='app', subtype='add_role') type='app', subtype='add_role')
@ -603,7 +603,7 @@ class Sphinx(object):
# register_canonical_role # register_canonical_role
logger.debug('[app] adding generic role: %r', (name, nodeclass)) logger.debug('[app] adding generic role: %r', (name, nodeclass))
if name in roles._roles: if name in roles._roles:
logger.warning(_('while setting up extension %s: role %r is ' logger.warning(__('while setting up extension %s: role %r is '
'already registered, it will be overridden'), 'already registered, it will be overridden'),
self._setting_up_extension[-1], name, self._setting_up_extension[-1], name,
type='app', subtype='add_generic_role') type='app', subtype='add_generic_role')

View File

@ -16,7 +16,7 @@ from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integ
from typing import Any, NamedTuple, Union from typing import Any, NamedTuple, Union
from sphinx.errors import ConfigError from sphinx.errors import ConfigError
from sphinx.locale import l_, _ from sphinx.locale import l_, __
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.i18n import format_date from sphinx.util.i18n import format_date
from sphinx.util.osutil import cd from sphinx.util.osutil import cd
@ -233,7 +233,7 @@ class Config(object):
else: else:
defvalue = self.values[name][0] defvalue = self.values[name][0]
if isinstance(defvalue, dict): if isinstance(defvalue, dict):
raise ValueError(_('cannot override dictionary config setting %r, ' raise ValueError(__('cannot override dictionary config setting %r, '
'ignoring (use %r to set individual elements)') % 'ignoring (use %r to set individual elements)') %
(name, name + '.key=value')) (name, name + '.key=value'))
elif isinstance(defvalue, list): elif isinstance(defvalue, list):
@ -242,12 +242,12 @@ class Config(object):
try: try:
return int(value) return int(value)
except ValueError: except ValueError:
raise ValueError(_('invalid number %r for config value %r, ignoring') % raise ValueError(__('invalid number %r for config value %r, ignoring') %
(value, name)) (value, name))
elif hasattr(defvalue, '__call__'): elif hasattr(defvalue, '__call__'):
return value return value
elif defvalue is not None and not isinstance(defvalue, string_types): elif defvalue is not None and not isinstance(defvalue, string_types):
raise ValueError(_('cannot override config setting %r with unsupported ' raise ValueError(__('cannot override config setting %r with unsupported '
'type, ignoring') % name) 'type, ignoring') % name)
else: else:
return value return value
@ -277,7 +277,8 @@ class Config(object):
config.setdefault(realvalname, {})[key] = value config.setdefault(realvalname, {})[key] = value
continue continue
elif valname not in self.values: elif valname not in self.values:
logger.warning(_('unknown config value %r in override, ignoring'), valname) logger.warning(__('unknown config value %r in override, ignoring'),
valname)
continue continue
if isinstance(value, string_types): if isinstance(value, string_types):
config[valname] = self.convert_overrides(valname, value) config[valname] = self.convert_overrides(valname, value)
@ -296,7 +297,7 @@ class Config(object):
if name.startswith('_'): if name.startswith('_'):
raise AttributeError(name) raise AttributeError(name)
if name not in self.values: if name not in self.values:
raise AttributeError(_('No such config value: %s') % name) raise AttributeError(__('No such config value: %s') % name)
default = self.values[name][0] default = self.values[name][0]
if hasattr(default, '__call__'): if hasattr(default, '__call__'):
return default(self) return default(self)

View File

@ -16,7 +16,7 @@ from docutils.parsers.rst import Directive, directives
from docutils.statemachine import ViewList from docutils.statemachine import ViewList
from sphinx import addnodes from sphinx import addnodes
from sphinx.locale import _ from sphinx.locale import __
from sphinx.util import logging from sphinx.util import logging
from sphinx.util import parselinenos from sphinx.util import parselinenos
from sphinx.util.nodes import set_source_info from sphinx.util.nodes import set_source_info
@ -63,7 +63,7 @@ def dedent_lines(lines, dedent, location=None):
return lines return lines
if any(s[:dedent].strip() for s in lines): if any(s[:dedent].strip() for s in lines):
logger.warning(_('Over dedent has detected'), location=location) logger.warning(__('Over dedent has detected'), location=location)
new_lines = [] new_lines = []
for line in lines: for line in lines:
@ -83,7 +83,7 @@ def container_wrapper(directive, literal_node, caption):
directive.state.nested_parse(ViewList([caption], source=''), directive.state.nested_parse(ViewList([caption], source=''),
directive.content_offset, parsed) directive.content_offset, parsed)
if isinstance(parsed[0], nodes.system_message): if isinstance(parsed[0], nodes.system_message):
msg = _('Invalid caption: %s' % parsed[0].astext()) msg = __('Invalid caption: %s' % parsed[0].astext())
raise ValueError(msg) raise ValueError(msg)
caption_node = nodes.caption(parsed[0].rawsource, '', caption_node = nodes.caption(parsed[0].rawsource, '',
*parsed[0].children) *parsed[0].children)
@ -198,7 +198,7 @@ class LiteralIncludeReader(object):
# type: () -> None # type: () -> None
for option1, option2 in self.INVALID_OPTIONS_PAIR: for option1, option2 in self.INVALID_OPTIONS_PAIR:
if option1 in self.options and option2 in self.options: if option1 in self.options and option2 in self.options:
raise ValueError(_('Cannot use both "%s" and "%s" options') % raise ValueError(__('Cannot use both "%s" and "%s" options') %
(option1, option2)) (option1, option2))
def read_file(self, filename, location=None): def read_file(self, filename, location=None):
@ -211,9 +211,9 @@ class LiteralIncludeReader(object):
return text.splitlines(True) return text.splitlines(True)
except (IOError, OSError): except (IOError, OSError):
raise IOError(_('Include file %r not found or reading it failed') % filename) raise IOError(__('Include file %r not found or reading it failed') % filename)
except UnicodeError: except UnicodeError:
raise UnicodeError(_('Encoding %r used for reading included file %r seems to ' raise UnicodeError(__('Encoding %r used for reading included file %r seems to '
'be wrong, try giving an :encoding: option') % 'be wrong, try giving an :encoding: option') %
(self.encoding, filename)) (self.encoding, filename))
@ -251,7 +251,7 @@ class LiteralIncludeReader(object):
analyzer = ModuleAnalyzer.for_file(self.filename, '') analyzer = ModuleAnalyzer.for_file(self.filename, '')
tags = analyzer.find_tags() tags = analyzer.find_tags()
if pyobject not in tags: if pyobject not in tags:
raise ValueError(_('Object named %r not found in include file %r') % raise ValueError(__('Object named %r not found in include file %r') %
(pyobject, self.filename)) (pyobject, self.filename))
else: else:
start = tags[pyobject][1] start = tags[pyobject][1]
@ -277,12 +277,12 @@ class LiteralIncludeReader(object):
if all(first + i == n for i, n in enumerate(linelist)): if all(first + i == n for i, n in enumerate(linelist)):
self.lineno_start += linelist[0] self.lineno_start += linelist[0]
else: else:
raise ValueError(_('Cannot use "lineno-match" with a disjoint ' raise ValueError(__('Cannot use "lineno-match" with a disjoint '
'set of "lines"')) 'set of "lines"'))
lines = [lines[n] for n in linelist if n < len(lines)] lines = [lines[n] for n in linelist if n < len(lines)]
if lines == []: if lines == []:
raise ValueError(_('Line spec %r: no lines pulled from include file %r') % raise ValueError(__('Line spec %r: no lines pulled from include file %r') %
(linespec, self.filename)) (linespec, self.filename))
return lines return lines

View File

@ -44,7 +44,7 @@ from sphinx.util.matching import compile_matchers
from sphinx.util.parallel import ParallelTasks, parallel_available, make_chunks from sphinx.util.parallel import ParallelTasks, parallel_available, make_chunks
from sphinx.util.websupport import is_commentable from sphinx.util.websupport import is_commentable
from sphinx.errors import SphinxError, ExtensionError from sphinx.errors import SphinxError, ExtensionError
from sphinx.locale import _ from sphinx.locale import __
from sphinx.transforms import SphinxTransformer from sphinx.transforms import SphinxTransformer
from sphinx.versioning import add_uids, merge_doctrees from sphinx.versioning import add_uids, merge_doctrees
from sphinx.deprecation import RemovedInSphinx17Warning, RemovedInSphinx20Warning from sphinx.deprecation import RemovedInSphinx17Warning, RemovedInSphinx20Warning
@ -565,7 +565,7 @@ class BuildEnvironment(object):
if parallel_available and len(docnames) > 5 and self.app.parallel > 1: if parallel_available and len(docnames) > 5 and self.app.parallel > 1:
for ext in itervalues(self.app.extensions): for ext in itervalues(self.app.extensions):
if ext.parallel_read_safe is None: if ext.parallel_read_safe is None:
logger.warning(_('the %s extension does not declare if it is safe ' logger.warning(__('the %s extension does not declare if it is safe '
'for parallel reading, assuming it isn\'t - please ' 'for parallel reading, assuming it isn\'t - please '
'ask the extension author to check and make it ' 'ask the extension author to check and make it '
'explicit'), ext.name) 'explicit'), ext.name)

View File

@ -17,7 +17,7 @@ from collections import OrderedDict, defaultdict
from six import itervalues from six import itervalues
from sphinx.errors import ExtensionError from sphinx.errors import ExtensionError
from sphinx.locale import _ from sphinx.locale import __
if False: if False:
# For type annotation # For type annotation
@ -54,13 +54,13 @@ class EventManager(object):
def add(self, name): def add(self, name):
# type: (unicode) -> None # type: (unicode) -> None
if name in self.events: if name in self.events:
raise ExtensionError(_('Event %r already present') % name) raise ExtensionError(__('Event %r already present') % name)
self.events[name] = '' self.events[name] = ''
def connect(self, name, callback): def connect(self, name, callback):
# type: (unicode, Callable) -> int # type: (unicode, Callable) -> int
if name not in self.events: if name not in self.events:
raise ExtensionError(_('Unknown event name: %s') % name) raise ExtensionError(__('Unknown event name: %s') % name)
listener_id = self.next_listener_id listener_id = self.next_listener_id
self.next_listener_id += 1 self.next_listener_id += 1

View File

@ -25,7 +25,7 @@ from docutils.statemachine import ViewList
import sphinx import sphinx
from sphinx.errors import SphinxError from sphinx.errors import SphinxError
from sphinx.locale import _ from sphinx.locale import _, __
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.i18n import search_image_for_language from sphinx.util.i18n import search_image_for_language
from sphinx.util.osutil import ensuredir, ENOENT, EPIPE, EINVAL from sphinx.util.osutil import ensuredir, ENOENT, EPIPE, EINVAL
@ -93,7 +93,7 @@ class Graphviz(Directive):
document = self.state.document document = self.state.document
if self.content: if self.content:
return [document.reporter.warning( return [document.reporter.warning(
_('Graphviz directive cannot have both content and ' __('Graphviz directive cannot have both content and '
'a filename argument'), line=self.lineno)] 'a filename argument'), line=self.lineno)]
env = self.state.document.settings.env env = self.state.document.settings.env
argument = search_image_for_language(self.arguments[0], env) argument = search_image_for_language(self.arguments[0], env)
@ -104,13 +104,13 @@ class Graphviz(Directive):
dotcode = fp.read() dotcode = fp.read()
except (IOError, OSError): except (IOError, OSError):
return [document.reporter.warning( return [document.reporter.warning(
_('External Graphviz file %r not found or reading ' __('External Graphviz file %r not found or reading '
'it failed') % filename, line=self.lineno)] 'it failed') % filename, line=self.lineno)]
else: else:
dotcode = '\n'.join(self.content) dotcode = '\n'.join(self.content)
if not dotcode.strip(): if not dotcode.strip():
return [self.state_machine.reporter.warning( return [self.state_machine.reporter.warning(
_('Ignoring "graphviz" directive without content.'), __('Ignoring "graphviz" directive without content.'),
line=self.lineno)] line=self.lineno)]
node = graphviz() node = graphviz()
node['code'] = dotcode node['code'] = dotcode
@ -201,7 +201,7 @@ def render_dot(self, code, options, format, prefix='graphviz'):
except OSError as err: except OSError as err:
if err.errno != ENOENT: # No such file or directory if err.errno != ENOENT: # No such file or directory
raise raise
logger.warning(_('dot command %r cannot be run (needed for graphviz ' logger.warning(__('dot command %r cannot be run (needed for graphviz '
'output), check the graphviz_dot setting'), graphviz_dot) 'output), check the graphviz_dot setting'), graphviz_dot)
if not hasattr(self.builder, '_graphviz_warned_dot'): if not hasattr(self.builder, '_graphviz_warned_dot'):
self.builder._graphviz_warned_dot = {} self.builder._graphviz_warned_dot = {}
@ -219,10 +219,10 @@ def render_dot(self, code, options, format, prefix='graphviz'):
stdout, stderr = p.stdout.read(), p.stderr.read() stdout, stderr = p.stdout.read(), p.stderr.read()
p.wait() p.wait()
if p.returncode != 0: if p.returncode != 0:
raise GraphvizError(_('dot exited with error:\n[stderr]\n%s\n' raise GraphvizError(__('dot exited with error:\n[stderr]\n%s\n'
'[stdout]\n%s') % (stderr, stdout)) '[stdout]\n%s') % (stderr, stdout))
if not path.isfile(outfn): if not path.isfile(outfn):
raise GraphvizError(_('dot did not produce an output file:\n[stderr]\n%s\n' raise GraphvizError(__('dot did not produce an output file:\n[stderr]\n%s\n'
'[stdout]\n%s') % (stderr, stdout)) '[stdout]\n%s') % (stderr, stdout))
return relfn, outfn return relfn, outfn
@ -233,7 +233,7 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
format = self.builder.config.graphviz_output_format format = self.builder.config.graphviz_output_format
try: try:
if format not in ('png', 'svg'): if format not in ('png', 'svg'):
raise GraphvizError(_("graphviz_output_format must be one of 'png', " raise GraphvizError(__("graphviz_output_format must be one of 'png', "
"'svg', but is %r") % format) "'svg', but is %r") % format)
fname, outfn = render_dot(self, code, options, format, prefix) fname, outfn = render_dot(self, code, options, format, prefix)
except GraphvizError as exc: except GraphvizError as exc:

View File

@ -11,7 +11,7 @@
import subprocess import subprocess
from sphinx.errors import ExtensionError from sphinx.errors import ExtensionError
from sphinx.locale import _ from sphinx.locale import __
from sphinx.transforms.post_transforms.images import ImageConverter from sphinx.transforms.post_transforms.images import ImageConverter
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.osutil import ENOENT, EPIPE, EINVAL from sphinx.util.osutil import ENOENT, EPIPE, EINVAL
@ -43,7 +43,7 @@ class ImagemagickConverter(ImageConverter):
else: else:
return False return False
except (OSError, IOError): except (OSError, IOError):
logger.warning(_('convert command %r cannot be run.' logger.warning(__('convert command %r cannot be run.'
'check the image_converter setting'), 'check the image_converter setting'),
self.config.image_converter) self.config.image_converter)
return False return False
@ -60,7 +60,7 @@ class ImagemagickConverter(ImageConverter):
except OSError as err: except OSError as err:
if err.errno != ENOENT: # No such file or directory if err.errno != ENOENT: # No such file or directory
raise raise
logger.warning(_('convert command %r cannot be run.' logger.warning(__('convert command %r cannot be run.'
'check the image_converter setting'), 'check the image_converter setting'),
self.config.image_converter) self.config.image_converter)
return False return False
@ -73,7 +73,7 @@ class ImagemagickConverter(ImageConverter):
stdout, stderr = p.stdout.read(), p.stderr.read() stdout, stderr = p.stdout.read(), p.stderr.read()
p.wait() p.wait()
if p.returncode != 0: if p.returncode != 0:
raise ExtensionError(_('convert exited with error:\n' raise ExtensionError(__('convert exited with error:\n'
'[stderr]\n%s\n[stdout]\n%s') % '[stderr]\n%s\n[stdout]\n%s') %
(stderr, stdout)) (stderr, stdout))

View File

@ -13,7 +13,7 @@ from docutils import nodes, utils
from docutils.parsers.rst import Directive, directives from docutils.parsers.rst import Directive, directives
from sphinx.roles import XRefRole from sphinx.roles import XRefRole
from sphinx.locale import _ from sphinx.locale import __
from sphinx.domains import Domain from sphinx.domains import Domain
from sphinx.util.nodes import make_refnode, set_source_info from sphinx.util.nodes import make_refnode, set_source_info
@ -103,7 +103,7 @@ class MathDomain(Domain):
equations = self.data['objects'] equations = self.data['objects']
if labelid in equations: if labelid in equations:
path = env.doc2path(equations[labelid][0]) path = env.doc2path(equations[labelid][0])
msg = _('duplicate label of equation %s, other instance in %s') % (labelid, path) msg = __('duplicate label of equation %s, other instance in %s') % (labelid, path)
raise UserWarning(msg) raise UserWarning(msg)
else: else:
eqno = self.get_next_equation_number(docname) eqno = self.get_next_equation_number(docname)

View File

@ -12,7 +12,7 @@
from six import iteritems from six import iteritems
from sphinx.errors import VersionRequirementError from sphinx.errors import VersionRequirementError
from sphinx.locale import _ from sphinx.locale import __
from sphinx.util import logging from sphinx.util import logging
if False: if False:
@ -50,12 +50,12 @@ def verify_required_extensions(app, requirements):
for extname, reqversion in iteritems(requirements): for extname, reqversion in iteritems(requirements):
extension = app.extensions.get(extname) extension = app.extensions.get(extname)
if extension is None: if extension is None:
logger.warning(_('The %s extension is required by needs_extensions settings,' logger.warning(__('The %s extension is required by needs_extensions settings,'
'but it is not loaded.'), extname) 'but it is not loaded.'), extname)
continue continue
if extension.version == 'unknown version' or reqversion > extension.version: if extension.version == 'unknown version' or reqversion > extension.version:
raise VersionRequirementError(_('This project needs the extension %s at least in ' raise VersionRequirementError(__('This project needs the extension %s at least in '
'version %s and therefore cannot be built with ' 'version %s and therefore cannot be built with '
'the loaded version (%s).') % 'the loaded version (%s).') %
(extname, reqversion, extension.version)) (extname, reqversion, extension.version))

View File

@ -242,6 +242,16 @@ else:
return message return message
def __(message):
# type: (unicode) -> unicode
"""A dummy wrapper to i18n'ize exceptions and command line messages.
In future, the messages are translated using LC_MESSAGES or any other
locale settings.
"""
return message
def init(locale_dirs, language, catalog='sphinx'): def init(locale_dirs, language, catalog='sphinx'):
# type: (List, unicode, unicode) -> Tuple[Any, bool] # type: (List, unicode, unicode) -> Tuple[Any, bool]
"""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

View File

@ -19,7 +19,7 @@ from sphinx.errors import ExtensionError, SphinxError, VersionRequirementError
from sphinx.extension import Extension from sphinx.extension import Extension
from sphinx.domains import ObjType from sphinx.domains import ObjType
from sphinx.domains.std import GenericObject, Target from sphinx.domains.std import GenericObject, Target
from sphinx.locale import _ from sphinx.locale import __
from sphinx.roles import XRefRole from sphinx.roles import XRefRole
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.docutils import directive_helper from sphinx.util.docutils import directive_helper
@ -53,9 +53,9 @@ class SphinxComponentRegistry(object):
def add_builder(self, builder): def add_builder(self, builder):
# type: (Type[Builder]) -> None # type: (Type[Builder]) -> None
if not hasattr(builder, 'name'): if not hasattr(builder, 'name'):
raise ExtensionError(_('Builder class %s has no "name" attribute') % builder) raise ExtensionError(__('Builder class %s has no "name" attribute') % builder)
if builder.name in self.builders: if builder.name in self.builders:
raise ExtensionError(_('Builder %r already exists (in module %s)') % raise ExtensionError(__('Builder %r already exists (in module %s)') %
(builder.name, self.builders[builder.name].__module__)) (builder.name, self.builders[builder.name].__module__))
self.builders[builder.name] = builder self.builders[builder.name] = builder
@ -69,7 +69,7 @@ class SphinxComponentRegistry(object):
try: try:
entry_point = next(entry_points) entry_point = next(entry_points)
except StopIteration: except StopIteration:
raise SphinxError(_('Builder name %s not registered or available' raise SphinxError(__('Builder name %s not registered or available'
' through entry point') % name) ' through entry point') % name)
self.load_extension(app, entry_point.module_name) self.load_extension(app, entry_point.module_name)
@ -77,14 +77,14 @@ class SphinxComponentRegistry(object):
def create_builder(self, app, name): def create_builder(self, app, name):
# type: (Sphinx, unicode) -> Builder # type: (Sphinx, unicode) -> Builder
if name not in self.builders: if name not in self.builders:
raise SphinxError(_('Builder name %s not registered') % name) raise SphinxError(__('Builder name %s not registered') % name)
return self.builders[name](app) return self.builders[name](app)
def add_domain(self, domain): def add_domain(self, domain):
# type: (Type[Domain]) -> None # type: (Type[Domain]) -> None
if domain.name in self.domains: if domain.name in self.domains:
raise ExtensionError(_('domain %s already registered') % domain.name) raise ExtensionError(__('domain %s already registered') % domain.name)
self.domains[domain.name] = domain self.domains[domain.name] = domain
def has_domain(self, domain): def has_domain(self, domain):
@ -99,9 +99,9 @@ class SphinxComponentRegistry(object):
def override_domain(self, domain): def override_domain(self, domain):
# type: (Type[Domain]) -> None # type: (Type[Domain]) -> None
if domain.name not in self.domains: if domain.name not in self.domains:
raise ExtensionError(_('domain %s not yet registered') % domain.name) raise ExtensionError(__('domain %s not yet registered') % domain.name)
if not issubclass(domain, self.domains[domain.name]): if not issubclass(domain, self.domains[domain.name]):
raise ExtensionError(_('new domain not a subclass of registered %s ' raise ExtensionError(__('new domain not a subclass of registered %s '
'domain') % domain.name) 'domain') % domain.name)
self.domains[domain.name] = domain self.domains[domain.name] = domain
@ -109,20 +109,20 @@ class SphinxComponentRegistry(object):
has_content=None, argument_spec=None, **option_spec): has_content=None, argument_spec=None, **option_spec):
# type: (unicode, unicode, Any, bool, Any, Any) -> None # type: (unicode, unicode, Any, bool, Any, Any) -> None
if domain not in self.domains: if domain not in self.domains:
raise ExtensionError(_('domain %s not yet registered') % domain) raise ExtensionError(__('domain %s not yet registered') % domain)
directive = directive_helper(obj, has_content, argument_spec, **option_spec) directive = directive_helper(obj, has_content, argument_spec, **option_spec)
self.domains[domain].directives[name] = directive self.domains[domain].directives[name] = directive
def add_role_to_domain(self, domain, name, role): def add_role_to_domain(self, domain, name, role):
# type: (unicode, unicode, Any) -> None # type: (unicode, unicode, Any) -> None
if domain not in self.domains: if domain not in self.domains:
raise ExtensionError(_('domain %s not yet registered') % domain) raise ExtensionError(__('domain %s not yet registered') % domain)
self.domains[domain].roles[name] = role self.domains[domain].roles[name] = role
def add_index_to_domain(self, domain, index): def add_index_to_domain(self, domain, index):
# type: (unicode, Type[Index]) -> None # type: (unicode, Type[Index]) -> None
if domain not in self.domains: if domain not in self.domains:
raise ExtensionError(_('domain %s not yet registered') % domain) raise ExtensionError(__('domain %s not yet registered') % domain)
self.domains[domain].indices.append(index) self.domains[domain].indices.append(index)
def add_object_type(self, directivename, rolename, indextemplate='', def add_object_type(self, directivename, rolename, indextemplate='',
@ -157,7 +157,7 @@ class SphinxComponentRegistry(object):
def add_source_parser(self, suffix, parser): def add_source_parser(self, suffix, parser):
# type: (unicode, Parser) -> None # type: (unicode, Parser) -> None
if suffix in self.source_parsers: if suffix in self.source_parsers:
raise ExtensionError(_('source_parser for %r is already registered') % suffix) raise ExtensionError(__('source_parser for %r is already registered') % suffix)
self.source_parsers[suffix] = parser self.source_parsers[suffix] = parser
def get_source_parsers(self): def get_source_parsers(self):
@ -184,7 +184,7 @@ class SphinxComponentRegistry(object):
if extname in app.extensions: # alread loaded if extname in app.extensions: # alread loaded
return return
if extname in EXTENSION_BLACKLIST: if extname in EXTENSION_BLACKLIST:
logger.warning(_('the extension %r was already merged with Sphinx since ' logger.warning(__('the extension %r was already merged with Sphinx since '
'version %s; this extension is ignored.'), 'version %s; this extension is ignored.'),
extname, EXTENSION_BLACKLIST[extname]) extname, EXTENSION_BLACKLIST[extname])
return return
@ -195,11 +195,11 @@ class SphinxComponentRegistry(object):
try: try:
mod = __import__(extname, None, None, ['setup']) mod = __import__(extname, None, None, ['setup'])
except ImportError as err: except ImportError as err:
logger.verbose(_('Original exception:\n') + traceback.format_exc()) logger.verbose(__('Original exception:\n') + traceback.format_exc())
raise ExtensionError(_('Could not import extension %s') % extname, err) raise ExtensionError(__('Could not import extension %s') % extname, err)
if not hasattr(mod, 'setup'): if not hasattr(mod, 'setup'):
logger.warning(_('extension %r has no setup() function; is it really ' logger.warning(__('extension %r has no setup() function; is it really '
'a Sphinx extension module?'), extname) 'a Sphinx extension module?'), extname)
metadata = {} # type: Dict[unicode, Any] metadata = {} # type: Dict[unicode, Any]
else: else:
@ -208,7 +208,7 @@ class SphinxComponentRegistry(object):
except VersionRequirementError as err: except VersionRequirementError as err:
# add the extension name to the version required # add the extension name to the version required
raise VersionRequirementError( raise VersionRequirementError(
_('The %s extension used by this project needs at least ' __('The %s extension used by this project needs at least '
'Sphinx v%s; it therefore cannot be built with this ' 'Sphinx v%s; it therefore cannot be built with this '
'version.') % (extname, err) 'version.') % (extname, err)
) )
@ -218,7 +218,7 @@ class SphinxComponentRegistry(object):
if extname == 'rst2pdf.pdfbuilder': if extname == 'rst2pdf.pdfbuilder':
metadata['parallel_read_safe'] = True metadata['parallel_read_safe'] = True
elif not isinstance(metadata, dict): elif not isinstance(metadata, dict):
logger.warning(_('extension %r returned an unsupported object from ' logger.warning(__('extension %r returned an unsupported object from '
'its setup() function; it should return None or a ' 'its setup() function; it should return None or a '
'metadata dictionary'), extname) 'metadata dictionary'), extname)

View File

@ -23,7 +23,7 @@ from six.moves import configparser
from sphinx import package_dir from sphinx import package_dir
from sphinx.deprecation import RemovedInSphinx20Warning from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.errors import ThemeError from sphinx.errors import ThemeError
from sphinx.locale import _ from sphinx.locale import __
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.osutil import ensuredir from sphinx.util.osutil import ensuredir
@ -80,15 +80,15 @@ class Theme(object):
try: try:
inherit = self.config.get('theme', 'inherit') inherit = self.config.get('theme', 'inherit')
except configparser.NoSectionError: except configparser.NoSectionError:
raise ThemeError(_('theme %r doesn\'t have "theme" setting') % name) raise ThemeError(__('theme %r doesn\'t have "theme" setting') % name)
except configparser.NoOptionError: except configparser.NoOptionError:
raise ThemeError(_('theme %r doesn\'t have "inherit" setting') % name) raise ThemeError(__('theme %r doesn\'t have "inherit" setting') % name)
if inherit != 'none': if inherit != 'none':
try: try:
self.base = factory.create(inherit) self.base = factory.create(inherit)
except ThemeError: except ThemeError:
raise ThemeError(_('no theme named %r found, inherited by %r') % raise ThemeError(__('no theme named %r found, inherited by %r') %
(inherit, name)) (inherit, name))
def get_theme_dirs(self): def get_theme_dirs(self):
@ -113,7 +113,7 @@ class Theme(object):
return self.base.get_config(section, name, default) return self.base.get_config(section, name, default)
if default is NODEFAULT: if default is NODEFAULT:
raise ThemeError(_('setting %s.%s occurs in none of the ' raise ThemeError(__('setting %s.%s occurs in none of the '
'searched theme configs') % (section, name)) 'searched theme configs') % (section, name))
else: else:
return default return default
@ -234,7 +234,7 @@ class HTMLThemeFactory(object):
if callable(target): if callable(target):
themedir = target() themedir = target()
if not isinstance(themedir, string_types): if not isinstance(themedir, string_types):
logger.warning(_('Theme extension %r does not respond correctly.') % logger.warning(__('Theme extension %r does not respond correctly.') %
entry_point.module_name) entry_point.module_name)
else: else:
themedir = target themedir = target
@ -261,7 +261,7 @@ class HTMLThemeFactory(object):
name = entry[:-4] name = entry[:-4]
themes[name] = pathname themes[name] = pathname
else: else:
logger.warning(_('file %r on theme path is not a valid ' logger.warning(__('file %r on theme path is not a valid '
'zipfile or contains no theme'), entry) 'zipfile or contains no theme'), entry)
else: else:
if path.isfile(path.join(pathname, THEMECONF)): if path.isfile(path.join(pathname, THEMECONF)):
@ -277,11 +277,11 @@ class HTMLThemeFactory(object):
if name not in self.themes: if name not in self.themes:
if name == 'sphinx_rtd_theme': if name == 'sphinx_rtd_theme':
raise ThemeError(_('sphinx_rtd_theme is no longer a hard dependency ' raise ThemeError(__('sphinx_rtd_theme is no longer a hard dependency '
'since version 1.4.0. Please install it manually.' 'since version 1.4.0. Please install it manually.'
'(pip install sphinx_rtd_theme)')) '(pip install sphinx_rtd_theme)'))
else: else:
raise ThemeError(_('no theme named %r found ' raise ThemeError(__('no theme named %r found '
'(missing theme.conf?)') % name) '(missing theme.conf?)') % name)
return Theme(name, self.themes[name], factory=self) return Theme(name, self.themes[name], factory=self)

View File

@ -17,7 +17,7 @@ from docutils.utils import get_source_line
from sphinx import addnodes from sphinx import addnodes
from sphinx.deprecation import RemovedInSphinx20Warning from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.environment import NoUri from sphinx.environment import NoUri
from sphinx.locale import _ from sphinx.locale import __
from sphinx.transforms import SphinxTransform from sphinx.transforms import SphinxTransform
from sphinx.util import logging from sphinx.util import logging
@ -135,7 +135,7 @@ class ReferencesResolver(SphinxTransform):
return None return None
if len(results) > 1: if len(results) > 1:
nice_results = ' or '.join(':%s:' % r[0] for r in results) nice_results = ' or '.join(':%s:' % r[0] for r in results)
logger.warning(_('more than one target found for \'any\' cross-' logger.warning(__('more than one target found for \'any\' cross-'
'reference %r: could be %s'), target, nice_results, 'reference %r: could be %s'), target, nice_results,
location=node) location=node)
res_role, newnode = results[0] res_role, newnode = results[0]
@ -165,10 +165,10 @@ class ReferencesResolver(SphinxTransform):
if domain and typ in domain.dangling_warnings: if domain and typ in domain.dangling_warnings:
msg = domain.dangling_warnings[typ] msg = domain.dangling_warnings[typ]
elif node.get('refdomain', 'std') not in ('', 'std'): elif node.get('refdomain', 'std') not in ('', 'std'):
msg = (_('%s:%s reference target not found: %%(target)s') % msg = (__('%s:%s reference target not found: %%(target)s') %
(node['refdomain'], typ)) (node['refdomain'], typ))
else: else:
msg = _('%r reference target not found: %%(target)s') % typ msg = __('%r reference target not found: %%(target)s') % typ
logger.warning(msg % {'target': target}, logger.warning(msg % {'target': target},
location=node, type='ref', subtype=typ) location=node, type='ref', subtype=typ)

View File

@ -22,7 +22,7 @@ from docutils.utils import Reporter
from docutils.parsers.rst import directives, roles, convert_directive_function from docutils.parsers.rst import directives, roles, convert_directive_function
from sphinx.errors import ExtensionError from sphinx.errors import ExtensionError
from sphinx.locale import _ from sphinx.locale import __
from sphinx.util import logging from sphinx.util import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -193,6 +193,6 @@ def directive_helper(obj, has_content=None, argument_spec=None, **option_spec):
return convert_directive_function(obj) return convert_directive_function(obj)
else: else:
if has_content or argument_spec or option_spec: if has_content or argument_spec or option_spec:
raise ExtensionError(_('when adding directive classes, no ' raise ExtensionError(__('when adding directive classes, no '
'additional arguments may be given')) 'additional arguments may be given'))
return obj return obj