mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Use sphinx.util.logging instead app.warn()
This commit is contained in:
parent
6d4e645409
commit
85dcd7baa8
@ -177,11 +177,11 @@ class Sphinx(object):
|
||||
self.tags = Tags(tags)
|
||||
self.config = Config(confdir, CONFIG_FILENAME,
|
||||
confoverrides or {}, self.tags)
|
||||
self.config.check_unicode(self.warn)
|
||||
self.config.check_unicode()
|
||||
# defer checking types until i18n has been initialized
|
||||
|
||||
# initialize some limited config variables before loading extensions
|
||||
self.config.pre_init_values(self.warn)
|
||||
self.config.pre_init_values()
|
||||
|
||||
# check the Sphinx version if requested
|
||||
if self.config.needs_sphinx and self.config.needs_sphinx > sphinx.__display_version__:
|
||||
@ -227,7 +227,7 @@ class Sphinx(object):
|
||||
)
|
||||
|
||||
# now that we know all config values, collect them from conf.py
|
||||
self.config.init_values(self.warn)
|
||||
self.config.init_values()
|
||||
|
||||
# check extension versions if requested
|
||||
if self.config.needs_extensions:
|
||||
@ -251,7 +251,7 @@ class Sphinx(object):
|
||||
# set up translation infrastructure
|
||||
self._init_i18n()
|
||||
# check all configuration values for permissible types
|
||||
self.config.check_types(self.warn)
|
||||
self.config.check_types()
|
||||
# set up source_parsers
|
||||
self._init_source_parsers()
|
||||
# set up the build environment
|
||||
@ -528,9 +528,9 @@ class Sphinx(object):
|
||||
if extension in self._extensions:
|
||||
return
|
||||
if extension in EXTENSION_BLACKLIST:
|
||||
self.warn('the extension %r was already merged with Sphinx since version %s; '
|
||||
'this extension is ignored.' % (
|
||||
extension, EXTENSION_BLACKLIST[extension]))
|
||||
logger.warning('the extension %r was already merged with Sphinx since version %s; '
|
||||
'this extension is ignored.',
|
||||
extension, EXTENSION_BLACKLIST[extension])
|
||||
return
|
||||
self._setting_up_extension.append(extension)
|
||||
try:
|
||||
@ -540,8 +540,8 @@ class Sphinx(object):
|
||||
raise ExtensionError('Could not import extension %s' % extension,
|
||||
err)
|
||||
if not hasattr(mod, 'setup'):
|
||||
self.warn('extension %r has no setup() function; is it really '
|
||||
'a Sphinx extension module?' % extension)
|
||||
logger.warning('extension %r has no setup() function; is it really '
|
||||
'a Sphinx extension module?', extension)
|
||||
ext_meta = None
|
||||
else:
|
||||
try:
|
||||
@ -561,9 +561,9 @@ class Sphinx(object):
|
||||
if not ext_meta.get('version'):
|
||||
ext_meta['version'] = 'unknown version'
|
||||
except Exception:
|
||||
self.warn('extension %r returned an unsupported object from '
|
||||
'its setup() function; it should return None or a '
|
||||
'metadata dictionary' % extension)
|
||||
logger.warning('extension %r returned an unsupported object from '
|
||||
'its setup() function; it should return None or a '
|
||||
'metadata dictionary', extension)
|
||||
ext_meta = {'version': 'unknown version'}
|
||||
self._extensions[extension] = mod
|
||||
self._extension_metadata[extension] = ext_meta
|
||||
@ -668,10 +668,10 @@ class Sphinx(object):
|
||||
self.debug('[app] adding node: %r', (node, kwds))
|
||||
if not kwds.pop('override', False) and \
|
||||
hasattr(nodes.GenericNodeVisitor, 'visit_' + node.__name__):
|
||||
self.warn('while setting up extension %s: node class %r is '
|
||||
'already registered, its visitors will be overridden' %
|
||||
(self._setting_up_extension, node.__name__),
|
||||
type='app', subtype='add_node')
|
||||
logger.warning('while setting up extension %s: node class %r is '
|
||||
'already registered, its visitors will be overridden',
|
||||
self._setting_up_extension, node.__name__,
|
||||
type='app', subtype='add_node')
|
||||
nodes._add_node_class_names([node.__name__])
|
||||
for key, val in iteritems(kwds):
|
||||
try:
|
||||
@ -722,10 +722,10 @@ class Sphinx(object):
|
||||
self.debug('[app] adding directive: %r',
|
||||
(name, obj, content, arguments, options))
|
||||
if name in directives._directives:
|
||||
self.warn('while setting up extension %s: directive %r is '
|
||||
'already registered, it will be overridden' %
|
||||
(self._setting_up_extension[-1], name),
|
||||
type='app', subtype='add_directive')
|
||||
logger.warning('while setting up extension %s: directive %r is '
|
||||
'already registered, it will be overridden',
|
||||
self._setting_up_extension[-1], name,
|
||||
type='app', subtype='add_directive')
|
||||
directives.register_directive(
|
||||
name, self._directive_helper(obj, content, arguments, **options))
|
||||
|
||||
@ -733,10 +733,10 @@ class Sphinx(object):
|
||||
# type: (unicode, Any) -> None
|
||||
self.debug('[app] adding role: %r', (name, role))
|
||||
if name in roles._roles:
|
||||
self.warn('while setting up extension %s: role %r is '
|
||||
'already registered, it will be overridden' %
|
||||
(self._setting_up_extension[-1], name),
|
||||
type='app', subtype='add_role')
|
||||
logger.warning('while setting up extension %s: role %r is '
|
||||
'already registered, it will be overridden',
|
||||
self._setting_up_extension[-1], name,
|
||||
type='app', subtype='add_role')
|
||||
roles.register_local_role(name, role)
|
||||
|
||||
def add_generic_role(self, name, nodeclass):
|
||||
@ -745,10 +745,10 @@ class Sphinx(object):
|
||||
# register_canonical_role
|
||||
self.debug('[app] adding generic role: %r', (name, nodeclass))
|
||||
if name in roles._roles:
|
||||
self.warn('while setting up extension %s: role %r is '
|
||||
'already registered, it will be overridden' %
|
||||
(self._setting_up_extension[-1], name),
|
||||
type='app', subtype='add_generic_role')
|
||||
logger.warning('while setting up extension %s: role %r is '
|
||||
'already registered, it will be overridden',
|
||||
self._setting_up_extension[-1], name,
|
||||
type='app', subtype='add_generic_role')
|
||||
role = roles.GenericRole(name, nodeclass)
|
||||
roles.register_local_role(name, role)
|
||||
|
||||
@ -891,10 +891,10 @@ class Sphinx(object):
|
||||
# type: (unicode, Parser) -> None
|
||||
self.debug('[app] adding search source_parser: %r, %r', suffix, parser)
|
||||
if suffix in self._additional_source_parsers:
|
||||
self.warn('while setting up extension %s: source_parser for %r is '
|
||||
'already registered, it will be overridden' %
|
||||
(self._setting_up_extension[-1], suffix),
|
||||
type='app', subtype='add_source_parser')
|
||||
logger.warning('while setting up extension %s: source_parser for %r is '
|
||||
'already registered, it will be overridden',
|
||||
self._setting_up_extension[-1], suffix,
|
||||
type='app', subtype='add_source_parser')
|
||||
self._additional_source_parsers[suffix] = parser
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@ except ImportError:
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx.util import i18n, path_stabilize
|
||||
from sphinx.util import i18n, path_stabilize, logging
|
||||
from sphinx.util.osutil import SEP, relative_uri
|
||||
from sphinx.util.i18n import find_catalog
|
||||
from sphinx.util.console import bold, darkgreen # type: ignore
|
||||
@ -284,13 +284,9 @@ class Builder(object):
|
||||
self.info(bold('building [%s]' % self.name) + ': ' + summary)
|
||||
|
||||
# while reading, collect all warnings from docutils
|
||||
warnings = []
|
||||
self.env.set_warnfunc(lambda *args, **kwargs: warnings.append((args, kwargs)))
|
||||
updated_docnames = set(self.env.update(self.config, self.srcdir,
|
||||
self.doctreedir, self.app))
|
||||
self.env.set_warnfunc(self.warn)
|
||||
for warning, kwargs in warnings:
|
||||
self.warn(*warning, **kwargs)
|
||||
with logging.pending_logging():
|
||||
updated_docnames = set(self.env.update(self.config, self.srcdir,
|
||||
self.doctreedir, self.app))
|
||||
|
||||
doccount = len(updated_docnames)
|
||||
self.info(bold('looking for now-outdated files... '), nonl=1)
|
||||
@ -376,25 +372,23 @@ class Builder(object):
|
||||
self.info('done')
|
||||
|
||||
warnings = [] # type: List[Tuple[Tuple, Dict]]
|
||||
self.env.set_warnfunc(lambda *args, **kwargs: warnings.append((args, kwargs)))
|
||||
if self.parallel_ok:
|
||||
# number of subprocesses is parallel-1 because the main process
|
||||
# is busy loading doctrees and doing write_doc_serialized()
|
||||
warnings = []
|
||||
self._write_parallel(sorted(docnames), warnings,
|
||||
nproc=self.app.parallel - 1)
|
||||
else:
|
||||
self._write_serial(sorted(docnames), warnings)
|
||||
self.env.set_warnfunc(self.warn)
|
||||
self._write_serial(sorted(docnames))
|
||||
|
||||
def _write_serial(self, docnames, warnings):
|
||||
# type: (Sequence[unicode], List[Tuple[Tuple, Dict]]) -> None
|
||||
for docname in self.app.status_iterator(
|
||||
docnames, 'writing output... ', darkgreen, len(docnames)):
|
||||
doctree = self.env.get_and_resolve_doctree(docname, self)
|
||||
self.write_doc_serialized(docname, doctree)
|
||||
self.write_doc(docname, doctree)
|
||||
for warning, kwargs in warnings:
|
||||
self.warn(*warning, **kwargs)
|
||||
def _write_serial(self, docnames):
|
||||
# type: (Sequence[unicode]) -> None
|
||||
with logging.pending_logging():
|
||||
for docname in self.app.status_iterator(
|
||||
docnames, 'writing output... ', darkgreen, len(docnames)):
|
||||
doctree = self.env.get_and_resolve_doctree(docname, self)
|
||||
self.write_doc_serialized(docname, doctree)
|
||||
self.write_doc(docname, doctree)
|
||||
|
||||
def _write_parallel(self, docnames, warnings, nproc):
|
||||
# type: (Iterable[unicode], List[Tuple[Tuple, Dict]], int) -> None
|
||||
|
@ -38,8 +38,7 @@ class ChangesBuilder(Builder):
|
||||
def init(self):
|
||||
# type: () -> None
|
||||
self.create_template_bridge()
|
||||
Theme.init_themes(self.confdir, self.config.html_theme_path,
|
||||
warn=self.warn)
|
||||
Theme.init_themes(self.confdir, self.config.html_theme_path)
|
||||
self.theme = Theme('default')
|
||||
self.templates.init(self, self.theme)
|
||||
|
||||
|
@ -159,10 +159,9 @@ class StandaloneHTMLBuilder(Builder):
|
||||
|
||||
def init_templates(self):
|
||||
# type: () -> None
|
||||
Theme.init_themes(self.confdir, self.config.html_theme_path,
|
||||
warn=self.warn)
|
||||
Theme.init_themes(self.confdir, self.config.html_theme_path)
|
||||
themename, themeoptions = self.get_theme_config()
|
||||
self.theme = Theme(themename, warn=self.warn)
|
||||
self.theme = Theme(themename)
|
||||
self.theme_options = themeoptions.copy()
|
||||
self.create_template_bridge()
|
||||
self.templates.init(self, self.theme)
|
||||
@ -314,8 +313,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
lufmt = self.config.html_last_updated_fmt
|
||||
if lufmt is not None:
|
||||
self.last_updated = format_date(lufmt or _('%b %d, %Y'),
|
||||
language=self.config.language,
|
||||
warn=self.warn)
|
||||
language=self.config.language)
|
||||
else:
|
||||
self.last_updated = None
|
||||
|
||||
|
@ -16,6 +16,7 @@ from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integ
|
||||
|
||||
from sphinx.errors import ConfigError
|
||||
from sphinx.locale import l_
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.i18n import format_date
|
||||
from sphinx.util.osutil import cd
|
||||
from sphinx.util.pycompat import execfile_, NoneType
|
||||
@ -25,6 +26,8 @@ if False:
|
||||
from typing import Any, Callable, Tuple # NOQA
|
||||
from sphinx.util.tags import Tags # NOQA
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
nonascii_re = re.compile(br'[\x80-\xff]')
|
||||
copyright_year_re = re.compile(r'^((\d{4}-)?)(\d{4})(?=[ ,])')
|
||||
|
||||
@ -166,8 +169,8 @@ class Config(object):
|
||||
config[k] = copyright_year_re.sub('\g<1>%s' % format_date('%Y'), # type: ignore # NOQA
|
||||
config[k])
|
||||
|
||||
def check_types(self, warn):
|
||||
# type: (Callable) -> None
|
||||
def check_types(self):
|
||||
# type: () -> None
|
||||
# check all values for deviation from the default value's type, since
|
||||
# that can result in TypeErrors all over the place
|
||||
# NB. since config values might use l_() we have to wait with calling
|
||||
@ -186,7 +189,7 @@ class Config(object):
|
||||
current = self[name]
|
||||
if isinstance(permitted, ENUM):
|
||||
if not permitted.match(current):
|
||||
warn(CONFIG_ENUM_WARNING.format(
|
||||
logger.warning(CONFIG_ENUM_WARNING.format(
|
||||
name=name, current=current, candidates=permitted.candidates))
|
||||
else:
|
||||
if type(current) is type(default):
|
||||
@ -201,22 +204,22 @@ class Config(object):
|
||||
continue # at least we share a non-trivial base class
|
||||
|
||||
if permitted:
|
||||
warn(CONFIG_PERMITTED_TYPE_WARNING.format(
|
||||
logger.warning(CONFIG_PERMITTED_TYPE_WARNING.format(
|
||||
name=name, current=type(current),
|
||||
permitted=str([cls.__name__ for cls in permitted])))
|
||||
else:
|
||||
warn(CONFIG_TYPE_WARNING.format(
|
||||
logger.warning(CONFIG_TYPE_WARNING.format(
|
||||
name=name, current=type(current), default=type(default)))
|
||||
|
||||
def check_unicode(self, warn):
|
||||
# type: (Callable) -> None
|
||||
def check_unicode(self):
|
||||
# type: () -> None
|
||||
# check all string values for non-ASCII characters in bytestrings,
|
||||
# since that can result in UnicodeErrors all over the place
|
||||
for name, value in iteritems(self._raw_config):
|
||||
if isinstance(value, binary_type) and nonascii_re.search(value): # type: ignore
|
||||
warn('the config value %r is set to a string with non-ASCII '
|
||||
'characters; this can lead to Unicode errors occurring. '
|
||||
'Please use Unicode strings, e.g. %r.' % (name, u'Content'))
|
||||
logger.warning('the config value %r is set to a string with non-ASCII '
|
||||
'characters; this can lead to Unicode errors occurring. '
|
||||
'Please use Unicode strings, e.g. %r.' % (name, u'Content'))
|
||||
|
||||
def convert_overrides(self, name, value):
|
||||
# type: (unicode, Any) -> Any
|
||||
@ -244,8 +247,8 @@ class Config(object):
|
||||
else:
|
||||
return value
|
||||
|
||||
def pre_init_values(self, warn):
|
||||
# type: (Callable) -> None
|
||||
def pre_init_values(self):
|
||||
# type: () -> None
|
||||
"""Initialize some limited config variables before loading extensions"""
|
||||
variables = ['needs_sphinx', 'suppress_warnings', 'html_translator_class']
|
||||
for name in variables:
|
||||
@ -255,10 +258,10 @@ class Config(object):
|
||||
elif name in self._raw_config:
|
||||
self.__dict__[name] = self._raw_config[name]
|
||||
except ValueError as exc:
|
||||
warn(exc)
|
||||
logger.warning("%s" % exc)
|
||||
|
||||
def init_values(self, warn):
|
||||
# type: (Callable) -> None
|
||||
def init_values(self):
|
||||
# type: () -> None
|
||||
config = self._raw_config
|
||||
for valname, value in iteritems(self.overrides):
|
||||
try:
|
||||
@ -267,14 +270,14 @@ class Config(object):
|
||||
config.setdefault(realvalname, {})[key] = value # type: ignore
|
||||
continue
|
||||
elif valname not in self.values:
|
||||
warn('unknown config value %r in override, ignoring' % valname)
|
||||
logger.warning('unknown config value %r in override, ignoring' % valname)
|
||||
continue
|
||||
if isinstance(value, string_types):
|
||||
config[valname] = self.convert_overrides(valname, value)
|
||||
else:
|
||||
config[valname] = value
|
||||
except ValueError as exc:
|
||||
warn(exc)
|
||||
logger.warning("%s" % exc)
|
||||
for name in config:
|
||||
if name in self.values:
|
||||
self.__dict__[name] = config[name]
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
from six import text_type
|
||||
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.pycompat import htmlescape
|
||||
from sphinx.util.texescape import tex_hl_escape_map_new
|
||||
from sphinx.ext import doctest
|
||||
@ -26,6 +27,8 @@ from pygments.styles import get_style_by_name
|
||||
from pygments.util import ClassNotFound
|
||||
from sphinx.pygments_styles import SphinxStyle, NoneStyle
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
lexers = dict(
|
||||
none = TextLexer(stripnl=False),
|
||||
python = PythonLexer(stripnl=False),
|
||||
@ -92,7 +95,7 @@ class PygmentsBridge(object):
|
||||
return '\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n' + \
|
||||
source + '\\end{Verbatim}\n'
|
||||
|
||||
def highlight_block(self, source, lang, opts=None, warn=None, force=False, **kwargs):
|
||||
def highlight_block(self, source, lang, opts=None, location=None, force=False, **kwargs):
|
||||
if not isinstance(source, text_type):
|
||||
source = source.decode()
|
||||
|
||||
@ -120,11 +123,9 @@ class PygmentsBridge(object):
|
||||
try:
|
||||
lexer = lexers[lang] = get_lexer_by_name(lang, **(opts or {}))
|
||||
except ClassNotFound:
|
||||
if warn:
|
||||
warn('Pygments lexer name %r is not known' % lang)
|
||||
lexer = lexers['none']
|
||||
else:
|
||||
raise
|
||||
logger.warning('Pygments lexer name %r is not known', lang,
|
||||
location=location)
|
||||
lexer = lexers['none']
|
||||
else:
|
||||
lexer.add_filter('raiseonerror')
|
||||
|
||||
@ -137,17 +138,16 @@ class PygmentsBridge(object):
|
||||
formatter = self.get_formatter(**kwargs)
|
||||
try:
|
||||
hlsource = highlight(source, lexer, formatter)
|
||||
except ErrorToken as exc:
|
||||
except ErrorToken:
|
||||
# this is most probably not the selected language,
|
||||
# so let it pass unhighlighted
|
||||
if lang == 'default':
|
||||
pass # automatic highlighting failed.
|
||||
elif warn:
|
||||
warn('Could not lex literal_block as "%s". '
|
||||
'Highlighting skipped.' % lang,
|
||||
type='misc', subtype='highlighting_failure')
|
||||
else:
|
||||
raise exc
|
||||
logger.warning('Could not lex literal_block as "%s". '
|
||||
'Highlighting skipped.', lang,
|
||||
type='misc', subtype='highlighting_failure',
|
||||
location=location)
|
||||
hlsource = highlight(source, lexers['none'], formatter)
|
||||
if self.dest == 'html':
|
||||
return hlsource
|
||||
|
@ -26,6 +26,9 @@ except ImportError:
|
||||
|
||||
from sphinx import package_dir
|
||||
from sphinx.errors import ThemeError
|
||||
from sphinx.util import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
@ -43,8 +46,8 @@ class Theme(object):
|
||||
themepath = [] # type: List[unicode]
|
||||
|
||||
@classmethod
|
||||
def init_themes(cls, confdir, theme_path, warn=None):
|
||||
# type: (unicode, unicode, Callable) -> None
|
||||
def init_themes(cls, confdir, theme_path):
|
||||
# type: (unicode, unicode) -> None
|
||||
"""Search all theme paths for available themes."""
|
||||
cls.themepath = list(theme_path)
|
||||
cls.themepath.append(path.join(package_dir, 'themes'))
|
||||
@ -62,9 +65,8 @@ class Theme(object):
|
||||
tname = theme[:-4]
|
||||
tinfo = zfile
|
||||
except Exception:
|
||||
if warn:
|
||||
warn('file %r on theme path is not a valid '
|
||||
'zipfile or contains no theme' % theme)
|
||||
logger.warning('file %r on theme path is not a valid '
|
||||
'zipfile or contains no theme', theme)
|
||||
continue
|
||||
else:
|
||||
if not path.isfile(path.join(themedir, theme, THEMECONF)):
|
||||
@ -105,8 +107,8 @@ class Theme(object):
|
||||
cls.themes[name] = (path.join(themedir, name), None)
|
||||
return
|
||||
|
||||
def __init__(self, name, warn=None):
|
||||
# type: (unicode, Callable) -> None
|
||||
def __init__(self, name):
|
||||
# type: (unicode) -> None
|
||||
if name not in self.themes:
|
||||
self.load_extra_theme(name)
|
||||
if name not in self.themes:
|
||||
@ -162,7 +164,7 @@ class Theme(object):
|
||||
raise ThemeError('no theme named %r found, inherited by %r' %
|
||||
(inherit, name))
|
||||
else:
|
||||
self.base = Theme(inherit, warn=warn)
|
||||
self.base = Theme(inherit)
|
||||
|
||||
def get_confstr(self, section, name, default=NODEFAULT):
|
||||
# type: (unicode, unicode, Any) -> Any
|
||||
|
@ -34,7 +34,6 @@ class DefaultSubstitutions(Transform):
|
||||
|
||||
def apply(self):
|
||||
# type: () -> None
|
||||
env = self.document.settings.env
|
||||
config = self.document.settings.env.config
|
||||
# only handle those not otherwise defined in the document
|
||||
to_handle = default_substitutions - set(self.document.substitution_defs)
|
||||
@ -45,7 +44,7 @@ class DefaultSubstitutions(Transform):
|
||||
if refname == 'today' and not text:
|
||||
# special handling: can also specify a strftime format
|
||||
text = format_date(config.today_fmt or _('%b %d, %Y'),
|
||||
language=config.language, warn=env.warn)
|
||||
language=config.language)
|
||||
ref.replace_self(nodes.Text(text, text))
|
||||
|
||||
|
||||
|
@ -22,9 +22,12 @@ from babel.messages.pofile import read_po
|
||||
from babel.messages.mofile import write_mo
|
||||
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.osutil import SEP, walk
|
||||
from sphinx.deprecation import RemovedInSphinx16Warning
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Callable # NOQA
|
||||
@ -171,8 +174,8 @@ date_format_mappings = {
|
||||
}
|
||||
|
||||
|
||||
def babel_format_date(date, format, locale, warn=None, formatter=babel.dates.format_date):
|
||||
# type: (datetime, unicode, unicode, Callable, Callable) -> unicode
|
||||
def babel_format_date(date, format, locale, formatter=babel.dates.format_date):
|
||||
# type: (datetime, unicode, unicode, Callable) -> unicode
|
||||
if locale is None:
|
||||
locale = 'en'
|
||||
|
||||
@ -187,15 +190,13 @@ def babel_format_date(date, format, locale, warn=None, formatter=babel.dates.for
|
||||
# fallback to English
|
||||
return formatter(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)
|
||||
|
||||
logger.warning('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, warn=None):
|
||||
# type: (str, datetime, unicode, Callable) -> unicode
|
||||
def format_date(format, date=None, language=None):
|
||||
# type: (str, datetime, unicode) -> unicode
|
||||
if format is None:
|
||||
format = 'medium'
|
||||
|
||||
@ -213,7 +214,7 @@ def format_date(format, date=None, language=None, warn=None):
|
||||
warnings.warn('LDML format support will be dropped at Sphinx-1.6',
|
||||
RemovedInSphinx16Warning)
|
||||
|
||||
return babel_format_date(date, format, locale=language, warn=warn,
|
||||
return babel_format_date(date, format, locale=language,
|
||||
formatter=babel.dates.format_datetime)
|
||||
else:
|
||||
# consider the format as ustrftime's and try to convert it to babel's
|
||||
|
@ -364,11 +364,10 @@ class HTMLTranslator(BaseTranslator):
|
||||
else:
|
||||
opts = {}
|
||||
|
||||
def warner(msg, **kwargs):
|
||||
self.builder.warn(msg, (self.builder.current_docname, node.line), **kwargs)
|
||||
highlighted = self.highlighter.highlight_block(
|
||||
node.rawsource, lang, opts=opts, warn=warner, linenos=linenos,
|
||||
**highlight_args)
|
||||
node.rawsource, lang, opts=opts, linenos=linenos,
|
||||
location=(self.builder.current_docname, node.line), **highlight_args
|
||||
)
|
||||
starttag = self.starttag(node, 'div', suffix='',
|
||||
CLASS='highlight-%s' % lang)
|
||||
self.body.append(starttag + highlighted + '</div>\n')
|
||||
|
@ -2155,12 +2155,10 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
else:
|
||||
opts = {}
|
||||
|
||||
def warner(msg, **kwargs):
|
||||
# type: (unicode) -> None
|
||||
self.builder.warn(msg, (self.curfilestack[-1], node.line), **kwargs)
|
||||
hlcode = self.highlighter.highlight_block(code, lang, opts=opts,
|
||||
warn=warner, linenos=linenos,
|
||||
**highlight_args)
|
||||
hlcode = self.highlighter.highlight_block(
|
||||
code, lang, opts=opts, linenos=linenos,
|
||||
location=(self.curfilestack[-1], node.line), **highlight_args
|
||||
)
|
||||
# workaround for Unicode issue
|
||||
hlcode = hlcode.replace(u'€', u'@texteuro[]')
|
||||
if self.in_footnote:
|
||||
|
@ -40,10 +40,10 @@ with "\\?": b?'here: >>>(\\\\|/)xbb<<<'
|
||||
"""
|
||||
|
||||
HTML_WARNINGS = ENV_WARNINGS + """\
|
||||
%(root)s/index.rst:\\d+: WARNING: no matching candidate for image URI u'foo.\\*'
|
||||
%(root)s/index.rst:\\d+: WARNING: Could not lex literal_block as "c". Highlighting skipped.
|
||||
%(root)s/index.rst:\\d+: WARNING: unknown option: &option
|
||||
%(root)s/index.rst:\\d+: WARNING: citation not found: missing
|
||||
%(root)s/index.rst:\\d+: WARNING: no matching candidate for image URI u'foo.\\*'
|
||||
%(root)s/index.rst:\\d+: WARNING: Could not lex literal_block as "c". Highlighting skipped.
|
||||
"""
|
||||
|
||||
if PY3:
|
||||
|
@ -87,7 +87,8 @@ def test_extension_values(app, status, warning):
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_errors_warnings(dir):
|
||||
@mock.patch("sphinx.config.logger")
|
||||
def test_errors_warnings(dir, logger):
|
||||
# test the error for syntax errors in the config file
|
||||
(dir / 'conf.py').write_text(u'project = \n', encoding='ascii')
|
||||
raises_msg(ConfigError, 'conf.py', Config, dir, 'conf.py', {}, None)
|
||||
@ -97,8 +98,9 @@ def test_errors_warnings(dir):
|
||||
u'# -*- coding: utf-8\n\nproject = u"Jägermeister"\n',
|
||||
encoding='utf-8')
|
||||
cfg = Config(dir, 'conf.py', {}, None)
|
||||
cfg.init_values(lambda warning: 1/0)
|
||||
cfg.init_values()
|
||||
assert cfg.project == u'Jägermeister'
|
||||
assert logger.called is False
|
||||
|
||||
# test the warning for bytestrings with non-ascii content
|
||||
# bytestrings with non-ascii content are a syntax error in python3 so we
|
||||
@ -108,13 +110,10 @@ def test_errors_warnings(dir):
|
||||
(dir / 'conf.py').write_text(
|
||||
u'# -*- coding: latin-1\nproject = "fooä"\n', encoding='latin-1')
|
||||
cfg = Config(dir, 'conf.py', {}, None)
|
||||
warned = [False]
|
||||
|
||||
def warn(msg):
|
||||
warned[0] = True
|
||||
|
||||
cfg.check_unicode(warn)
|
||||
assert warned[0]
|
||||
assert logger.warning.called is False
|
||||
cfg.check_unicode()
|
||||
assert logger.warning.called is True
|
||||
|
||||
|
||||
@with_tempdir
|
||||
@ -152,14 +151,16 @@ def test_needs_sphinx():
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_config_eol(tmpdir):
|
||||
@mock.patch("sphinx.config.logger")
|
||||
def test_config_eol(tmpdir, logger):
|
||||
# test config file's eol patterns: LF, CRLF
|
||||
configfile = tmpdir / 'conf.py'
|
||||
for eol in (b'\n', b'\r\n'):
|
||||
configfile.write_bytes(b'project = "spam"' + eol)
|
||||
cfg = Config(tmpdir, 'conf.py', {}, None)
|
||||
cfg.init_values(lambda warning: 1/0)
|
||||
cfg.init_values()
|
||||
assert cfg.project == u'spam'
|
||||
assert logger.called is False
|
||||
|
||||
|
||||
@with_app(confoverrides={'master_doc': 123,
|
||||
|
@ -9,9 +9,9 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
import mock
|
||||
from pygments.lexer import RegexLexer
|
||||
from pygments.token import Text, Name
|
||||
from pygments.filters import ErrorToken
|
||||
from pygments.formatters.html import HtmlFormatter
|
||||
|
||||
from sphinx.highlighting import PygmentsBridge
|
||||
@ -89,7 +89,8 @@ def test_trim_doctest_flags():
|
||||
PygmentsBridge.html_formatter = HtmlFormatter
|
||||
|
||||
|
||||
def test_default_highlight():
|
||||
@mock.patch('sphinx.highlighting.logger')
|
||||
def test_default_highlight(logger):
|
||||
bridge = PygmentsBridge('html')
|
||||
|
||||
# default: highlights as python3
|
||||
@ -107,8 +108,7 @@ def test_default_highlight():
|
||||
'<span class="s2">"Hello sphinx world"</span>\n</pre></div>\n')
|
||||
|
||||
# python3: raises error if highlighting failed
|
||||
try:
|
||||
ret = bridge.highlight_block('reST ``like`` text', 'python3')
|
||||
assert False, "highlight_block() does not raise any exceptions"
|
||||
except ErrorToken:
|
||||
pass # raise parsing error
|
||||
ret = bridge.highlight_block('reST ``like`` text', 'python3')
|
||||
logger.warning.assert_called_with('Could not lex literal_block as "%s". '
|
||||
'Highlighting skipped.', 'python3',
|
||||
type='misc', subtype='highlighting_failure', location=None)
|
||||
|
Loading…
Reference in New Issue
Block a user