mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Use loggers
This commit is contained in:
parent
6bf201533a
commit
e755a8c004
@ -233,9 +233,9 @@ class Sphinx(object):
|
|||||||
if self.config.needs_extensions:
|
if self.config.needs_extensions:
|
||||||
for extname, needs_ver in self.config.needs_extensions.items():
|
for extname, needs_ver in self.config.needs_extensions.items():
|
||||||
if extname not in self._extensions:
|
if extname not in self._extensions:
|
||||||
self.warn('needs_extensions config value specifies a '
|
logger.warning('needs_extensions config value specifies a '
|
||||||
'version requirement for extension %s, but it is '
|
'version requirement for extension %s, but it is '
|
||||||
'not loaded' % extname)
|
'not loaded', extname)
|
||||||
continue
|
continue
|
||||||
has_ver = self._extension_metadata[extname]['version']
|
has_ver = self._extension_metadata[extname]['version']
|
||||||
if has_ver == 'unknown version' or needs_ver > has_ver:
|
if has_ver == 'unknown version' or needs_ver > has_ver:
|
||||||
@ -246,7 +246,7 @@ class Sphinx(object):
|
|||||||
|
|
||||||
# check primary_domain if requested
|
# check primary_domain if requested
|
||||||
if self.config.primary_domain and self.config.primary_domain not in self.domains:
|
if self.config.primary_domain and self.config.primary_domain not in self.domains:
|
||||||
self.warn('primary_domain %r not found, ignored.' % self.config.primary_domain)
|
logger.warning('primary_domain %r not found, ignored.', self.config.primary_domain)
|
||||||
|
|
||||||
# set up translation infrastructure
|
# set up translation infrastructure
|
||||||
self._init_i18n()
|
self._init_i18n()
|
||||||
|
@ -161,9 +161,8 @@ class Builder(object):
|
|||||||
if candidate:
|
if candidate:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
self.warn(
|
logger.warn_node('no matching candidate for image URI %r' % node['uri'],
|
||||||
'no matching candidate for image URI %r' % node['uri'],
|
node)
|
||||||
'%s:%s' % (node.source, getattr(node, 'line', '')))
|
|
||||||
continue
|
continue
|
||||||
node['uri'] = candidate
|
node['uri'] = candidate
|
||||||
else:
|
else:
|
||||||
@ -246,13 +245,13 @@ class Builder(object):
|
|||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
filename = path.normpath(path.abspath(filename))
|
filename = path.normpath(path.abspath(filename))
|
||||||
if not filename.startswith(self.srcdir):
|
if not filename.startswith(self.srcdir):
|
||||||
self.warn('file %r given on command line is not under the '
|
logger.warning('file %r given on command line is not under the '
|
||||||
'source directory, ignoring' % filename)
|
'source directory, ignoring', filename)
|
||||||
continue
|
continue
|
||||||
if not (path.isfile(filename) or
|
if not (path.isfile(filename) or
|
||||||
any(path.isfile(filename + suffix) for suffix in suffixes)):
|
any(path.isfile(filename + suffix) for suffix in suffixes)):
|
||||||
self.warn('file %r given on command line does not exist, '
|
logger.warning('file %r given on command line does not exist, '
|
||||||
'ignoring' % filename)
|
'ignoring', filename)
|
||||||
continue
|
continue
|
||||||
filename = filename[dirlen:]
|
filename = filename[dirlen:]
|
||||||
for suffix in suffixes:
|
for suffix in suffixes:
|
||||||
@ -297,7 +296,7 @@ class Builder(object):
|
|||||||
updated_docnames.add(docname)
|
updated_docnames.add(docname)
|
||||||
outdated = len(updated_docnames) - doccount
|
outdated = len(updated_docnames) - doccount
|
||||||
if outdated:
|
if outdated:
|
||||||
logger.info('%d found' % outdated)
|
logger.info('%d found', outdated)
|
||||||
else:
|
else:
|
||||||
logger.info('none found')
|
logger.info('none found')
|
||||||
|
|
||||||
@ -330,8 +329,8 @@ class Builder(object):
|
|||||||
for extname, md in self.app._extension_metadata.items():
|
for extname, md in self.app._extension_metadata.items():
|
||||||
par_ok = md.get('parallel_write_safe', True)
|
par_ok = md.get('parallel_write_safe', True)
|
||||||
if not par_ok:
|
if not par_ok:
|
||||||
self.app.warn('the %s extension is not safe for parallel '
|
logger.warning('the %s extension is not safe for parallel '
|
||||||
'writing, doing serial write' % extname)
|
'writing, doing serial write', extname)
|
||||||
self.parallel_ok = False
|
self.parallel_ok = False
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -374,12 +373,10 @@ class Builder(object):
|
|||||||
self.prepare_writing(docnames)
|
self.prepare_writing(docnames)
|
||||||
logger.info('done')
|
logger.info('done')
|
||||||
|
|
||||||
warnings = [] # type: List[Tuple[Tuple, Dict]]
|
|
||||||
if self.parallel_ok:
|
if self.parallel_ok:
|
||||||
# number of subprocesses is parallel-1 because the main process
|
# number of subprocesses is parallel-1 because the main process
|
||||||
# is busy loading doctrees and doing write_doc_serialized()
|
# is busy loading doctrees and doing write_doc_serialized()
|
||||||
warnings = []
|
self._write_parallel(sorted(docnames),
|
||||||
self._write_parallel(sorted(docnames), warnings,
|
|
||||||
nproc=self.app.parallel - 1)
|
nproc=self.app.parallel - 1)
|
||||||
else:
|
else:
|
||||||
self._write_serial(sorted(docnames))
|
self._write_serial(sorted(docnames))
|
||||||
@ -393,21 +390,12 @@ class Builder(object):
|
|||||||
self.write_doc_serialized(docname, doctree)
|
self.write_doc_serialized(docname, doctree)
|
||||||
self.write_doc(docname, doctree)
|
self.write_doc(docname, doctree)
|
||||||
|
|
||||||
def _write_parallel(self, docnames, warnings, nproc):
|
def _write_parallel(self, docnames, nproc):
|
||||||
# type: (Iterable[unicode], List[Tuple[Tuple, Dict]], int) -> None
|
# type: (Iterable[unicode], int) -> None
|
||||||
def write_process(docs):
|
def write_process(docs):
|
||||||
# type: (List[Tuple[unicode, nodes.Node]]) -> List[Tuple[Tuple, Dict]]
|
# type: (List[Tuple[unicode, nodes.Node]]) -> None
|
||||||
local_warnings = []
|
|
||||||
|
|
||||||
def warnfunc(*args, **kwargs):
|
|
||||||
local_warnings.append((args, kwargs))
|
|
||||||
self.env.set_warnfunc(warnfunc)
|
|
||||||
for docname, doctree in docs:
|
for docname, doctree in docs:
|
||||||
self.write_doc(docname, doctree)
|
self.write_doc(docname, doctree)
|
||||||
return local_warnings
|
|
||||||
|
|
||||||
def add_warnings(docs, wlist):
|
|
||||||
warnings.extend(wlist)
|
|
||||||
|
|
||||||
# warm up caches/compile templates using the first document
|
# warm up caches/compile templates using the first document
|
||||||
firstname, docnames = docnames[0], docnames[1:] # type: ignore
|
firstname, docnames = docnames[0], docnames[1:] # type: ignore
|
||||||
@ -425,15 +413,12 @@ class Builder(object):
|
|||||||
doctree = self.env.get_and_resolve_doctree(docname, self)
|
doctree = self.env.get_and_resolve_doctree(docname, self)
|
||||||
self.write_doc_serialized(docname, doctree)
|
self.write_doc_serialized(docname, doctree)
|
||||||
arg.append((docname, doctree))
|
arg.append((docname, doctree))
|
||||||
tasks.add_task(write_process, arg, add_warnings)
|
tasks.add_task(write_process, arg)
|
||||||
|
|
||||||
# make sure all threads have finished
|
# make sure all threads have finished
|
||||||
logger.info(bold('waiting for workers...'))
|
logger.info(bold('waiting for workers...'))
|
||||||
tasks.join()
|
tasks.join()
|
||||||
|
|
||||||
for warning, kwargs in warnings:
|
|
||||||
self.warn(*warning, **kwargs)
|
|
||||||
|
|
||||||
def prepare_writing(self, docnames):
|
def prepare_writing(self, docnames):
|
||||||
# type: (Set[unicode]) -> None
|
# type: (Set[unicode]) -> None
|
||||||
"""A place where you can add logic before :meth:`write_doc` is run"""
|
"""A place where you can add logic before :meth:`write_doc` is run"""
|
||||||
|
@ -184,9 +184,8 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
logger.info('done')
|
logger.info('done')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.warn('cannot copy icon file %r: %s' %
|
logger.warning('cannot copy icon file %r: %s',
|
||||||
(path.join(self.srcdir, self.config.applehelp_icon),
|
path.join(self.srcdir, self.config.applehelp_icon), err)
|
||||||
err))
|
|
||||||
del info_plist['HPDBookIconPath']
|
del info_plist['HPDBookIconPath']
|
||||||
|
|
||||||
# Build the access page
|
# Build the access page
|
||||||
@ -223,8 +222,8 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
if self.config.applehelp_disable_external_tools:
|
if self.config.applehelp_disable_external_tools:
|
||||||
logger.info('skipping')
|
logger.info('skipping')
|
||||||
|
|
||||||
self.warn('you will need to index this help book with:\n %s'
|
logger.warning('you will need to index this help book with:\n %s',
|
||||||
% (' '.join([pipes.quote(arg) for arg in args])))
|
' '.join([pipes.quote(arg) for arg in args]))
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
p = subprocess.Popen(args,
|
p = subprocess.Popen(args,
|
||||||
@ -256,9 +255,8 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
if self.config.applehelp_disable_external_tools:
|
if self.config.applehelp_disable_external_tools:
|
||||||
logger.info('skipping')
|
logger.info('skipping')
|
||||||
|
logger.warning('you will need to sign this help book with:\n %s',
|
||||||
self.warn('you will need to sign this help book with:\n %s'
|
' '.join([pipes.quote(arg) for arg in args]))
|
||||||
% (' '.join([pipes.quote(arg) for arg in args])))
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
p = subprocess.Popen(args,
|
p = subprocess.Popen(args,
|
||||||
|
@ -136,7 +136,7 @@ class ChangesBuilder(Builder):
|
|||||||
try:
|
try:
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
self.warn('could not read %r for changelog creation' % docname)
|
logger.warning('could not read %r for changelog creation', docname)
|
||||||
continue
|
continue
|
||||||
targetfn = path.join(self.outdir, 'rst', os_path(docname)) + '.html'
|
targetfn = path.join(self.outdir, 'rst', os_path(docname)) + '.html'
|
||||||
ensuredir(path.dirname(targetfn))
|
ensuredir(path.dirname(targetfn))
|
||||||
|
@ -477,14 +477,14 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
img = Image.open(path.join(self.srcdir, src))
|
img = Image.open(path.join(self.srcdir, src))
|
||||||
except IOError:
|
except IOError:
|
||||||
if not self.is_vector_graphics(src):
|
if not self.is_vector_graphics(src):
|
||||||
self.warn('cannot read image file %r: copying it instead' %
|
logger.warning('cannot read image file %r: copying it instead',
|
||||||
(path.join(self.srcdir, src), ))
|
path.join(self.srcdir, src))
|
||||||
try:
|
try:
|
||||||
copyfile(path.join(self.srcdir, src),
|
copyfile(path.join(self.srcdir, src),
|
||||||
path.join(self.outdir, self.imagedir, dest))
|
path.join(self.outdir, self.imagedir, dest))
|
||||||
except (IOError, OSError) as err:
|
except (IOError, OSError) as err:
|
||||||
self.warn('cannot copy image file %r: %s' %
|
logger.warning('cannot copy image file %r: %s',
|
||||||
(path.join(self.srcdir, src), err))
|
path.join(self.srcdir, src), err)
|
||||||
continue
|
continue
|
||||||
if self.config.epub_fix_images:
|
if self.config.epub_fix_images:
|
||||||
if img.mode in ('P',):
|
if img.mode in ('P',):
|
||||||
@ -499,8 +499,8 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
try:
|
try:
|
||||||
img.save(path.join(self.outdir, self.imagedir, dest))
|
img.save(path.join(self.outdir, self.imagedir, dest))
|
||||||
except (IOError, OSError) as err:
|
except (IOError, OSError) as err:
|
||||||
self.warn('cannot write image file %r: %s' %
|
logger.warning('cannot write image file %r: %s',
|
||||||
(path.join(self.srcdir, src), err))
|
path.join(self.srcdir, src), err)
|
||||||
|
|
||||||
def copy_image_files(self):
|
def copy_image_files(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
@ -510,7 +510,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
if self.images:
|
if self.images:
|
||||||
if self.config.epub_fix_images or self.config.epub_max_image_width:
|
if self.config.epub_fix_images or self.config.epub_max_image_width:
|
||||||
if not Image:
|
if not Image:
|
||||||
self.warn('PIL not found - copying image files')
|
logger.warning('PIL not found - copying image files')
|
||||||
super(EpubBuilder, self).copy_image_files()
|
super(EpubBuilder, self).copy_image_files()
|
||||||
else:
|
else:
|
||||||
self.copy_image_files_pil()
|
self.copy_image_files_pil()
|
||||||
@ -551,14 +551,14 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
def build_mimetype(self, outdir, outname):
|
def build_mimetype(self, outdir, outname):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (unicode, unicode) -> None
|
||||||
"""Write the metainfo file mimetype."""
|
"""Write the metainfo file mimetype."""
|
||||||
logger.info('writing %s file...' % outname)
|
logger.info('writing %s file...', outname)
|
||||||
with codecs.open(path.join(outdir, outname), 'w', 'utf-8') as f: # type: ignore
|
with codecs.open(path.join(outdir, outname), 'w', 'utf-8') as f: # type: ignore
|
||||||
f.write(self.mimetype_template)
|
f.write(self.mimetype_template)
|
||||||
|
|
||||||
def build_container(self, outdir, outname):
|
def build_container(self, outdir, outname):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (unicode, unicode) -> None
|
||||||
"""Write the metainfo file META-INF/cointainer.xml."""
|
"""Write the metainfo file META-INF/cointainer.xml."""
|
||||||
logger.info('writing %s file...' % outname)
|
logger.info('writing %s file...', outname)
|
||||||
fn = path.join(outdir, outname)
|
fn = path.join(outdir, outname)
|
||||||
try:
|
try:
|
||||||
os.mkdir(path.dirname(fn))
|
os.mkdir(path.dirname(fn))
|
||||||
@ -593,7 +593,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
"""Write the metainfo file content.opf It contains bibliographic data,
|
"""Write the metainfo file content.opf It contains bibliographic data,
|
||||||
a file list and the spine (the reading order).
|
a file list and the spine (the reading order).
|
||||||
"""
|
"""
|
||||||
logger.info('writing %s file...' % outname)
|
logger.info('writing %s file...', outname)
|
||||||
|
|
||||||
# files
|
# files
|
||||||
if not outdir.endswith(os.sep):
|
if not outdir.endswith(os.sep):
|
||||||
@ -618,8 +618,8 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
# we always have JS and potentially OpenSearch files, don't
|
# we always have JS and potentially OpenSearch files, don't
|
||||||
# always warn about them
|
# always warn about them
|
||||||
if ext not in ('.js', '.xml'):
|
if ext not in ('.js', '.xml'):
|
||||||
self.warn('unknown mimetype for %s, ignoring' % filename,
|
logger.warning('unknown mimetype for %s, ignoring', filename,
|
||||||
type='epub', subtype='unknown_project_files')
|
type='epub', subtype='unknown_project_files')
|
||||||
continue
|
continue
|
||||||
filename = filename.replace(os.sep, '/')
|
filename = filename.replace(os.sep, '/')
|
||||||
projectfiles.append(self.file_template % {
|
projectfiles.append(self.file_template % {
|
||||||
@ -804,7 +804,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
def build_toc(self, outdir, outname):
|
def build_toc(self, outdir, outname):
|
||||||
# type: (unicode, unicode) -> None
|
# type: (unicode, unicode) -> None
|
||||||
"""Write the metainfo file toc.ncx."""
|
"""Write the metainfo file toc.ncx."""
|
||||||
logger.info('writing %s file...' % outname)
|
logger.info('writing %s file...', outname)
|
||||||
|
|
||||||
if self.config.epub_tocscope == 'default':
|
if self.config.epub_tocscope == 'default':
|
||||||
doctree = self.env.get_and_resolve_doctree(self.config.master_doc,
|
doctree = self.env.get_and_resolve_doctree(self.config.master_doc,
|
||||||
@ -828,7 +828,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
It is a zip file with the mimetype file stored uncompressed as the first
|
It is a zip file with the mimetype file stored uncompressed as the first
|
||||||
entry.
|
entry.
|
||||||
"""
|
"""
|
||||||
logger.info('writing %s file...' % outname)
|
logger.info('writing %s file...', outname)
|
||||||
projectfiles = ['META-INF/container.xml', 'content.opf', 'toc.ncx'] # type: List[unicode] # NOQA
|
projectfiles = ['META-INF/container.xml', 'content.opf', 'toc.ncx'] # type: List[unicode] # NOQA
|
||||||
projectfiles.extend(self.files)
|
projectfiles.extend(self.files)
|
||||||
epub = zipfile.ZipFile(path.join(outdir, outname), 'w', # type: ignore
|
epub = zipfile.ZipFile(path.join(outdir, outname), 'w', # type: ignore
|
||||||
|
@ -239,7 +239,7 @@ class Epub3Builder(EpubBuilder):
|
|||||||
|
|
||||||
def build_navigation_doc(self, outdir, outname):
|
def build_navigation_doc(self, outdir, outname):
|
||||||
"""Write the metainfo file nav.xhtml."""
|
"""Write the metainfo file nav.xhtml."""
|
||||||
logger.info('writing %s file...' % outname)
|
logger.info('writing %s file...', outname)
|
||||||
|
|
||||||
if self.config.epub_tocscope == 'default':
|
if self.config.epub_tocscope == 'default':
|
||||||
doctree = self.env.get_and_resolve_doctree(
|
doctree = self.env.get_and_resolve_doctree(
|
||||||
@ -262,16 +262,16 @@ class Epub3Builder(EpubBuilder):
|
|||||||
|
|
||||||
def validate_config_values(app):
|
def validate_config_values(app):
|
||||||
if app.config.epub3_description is not None:
|
if app.config.epub3_description is not None:
|
||||||
app.warn('epub3_description is deprecated. Use epub_description instead.')
|
logger.warning('epub3_description is deprecated. Use epub_description instead.')
|
||||||
app.config.epub_description = app.config.epub3_description
|
app.config.epub_description = app.config.epub3_description
|
||||||
|
|
||||||
if app.config.epub3_contributor is not None:
|
if app.config.epub3_contributor is not None:
|
||||||
app.warn('epub3_contributor is deprecated. Use epub_contributor instead.')
|
logger.warning('epub3_contributor is deprecated. Use epub_contributor instead.')
|
||||||
app.config.epub_contributor = app.config.epub3_contributor
|
app.config.epub_contributor = app.config.epub3_contributor
|
||||||
|
|
||||||
if app.config.epub3_page_progression_direction is not None:
|
if app.config.epub3_page_progression_direction is not None:
|
||||||
app.warn('epub3_page_progression_direction option is deprecated'
|
logger.warning('epub3_page_progression_direction option is deprecated'
|
||||||
' from 1.5. Use epub_writing_mode instead.')
|
' from 1.5. Use epub_writing_mode instead.')
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
|
@ -220,7 +220,7 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
# type: () -> None
|
# type: () -> None
|
||||||
files = self._collect_templates()
|
files = self._collect_templates()
|
||||||
logger.info(bold('building [%s]: ' % self.name), nonl=1)
|
logger.info(bold('building [%s]: ' % self.name), nonl=1)
|
||||||
logger.info('targets for %d template files' % len(files))
|
logger.info('targets for %d template files', len(files))
|
||||||
|
|
||||||
extract_translations = self.templates.environment.extract_translations
|
extract_translations = self.templates.environment.extract_translations
|
||||||
|
|
||||||
|
@ -209,8 +209,8 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
if tag != 'tags':
|
if tag != 'tags':
|
||||||
raise ValueError
|
raise ValueError
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.warn('unsupported build info format in %r, building all' %
|
logger.warning('unsupported build info format in %r, building all',
|
||||||
path.join(self.outdir, '.buildinfo'))
|
path.join(self.outdir, '.buildinfo'))
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
if old_config_hash != self.config_hash or \
|
if old_config_hash != self.config_hash or \
|
||||||
@ -325,10 +325,10 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
favicon = self.config.html_favicon and \
|
favicon = self.config.html_favicon and \
|
||||||
path.basename(self.config.html_favicon) or ''
|
path.basename(self.config.html_favicon) or ''
|
||||||
if favicon and os.path.splitext(favicon)[1] != '.ico':
|
if favicon and os.path.splitext(favicon)[1] != '.ico':
|
||||||
self.warn('html_favicon is not an .ico file')
|
logger.warning('html_favicon is not an .ico file')
|
||||||
|
|
||||||
if not isinstance(self.config.html_use_opensearch, string_types):
|
if not isinstance(self.config.html_use_opensearch, string_types):
|
||||||
self.warn('html_use_opensearch config value must now be a string')
|
logger.warning('html_use_opensearch config value must now be a string')
|
||||||
|
|
||||||
self.relations = self.env.collect_relations()
|
self.relations = self.env.collect_relations()
|
||||||
|
|
||||||
@ -595,8 +595,8 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
copyfile(path.join(self.srcdir, src),
|
copyfile(path.join(self.srcdir, src),
|
||||||
path.join(self.outdir, self.imagedir, dest))
|
path.join(self.outdir, self.imagedir, dest))
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.warn('cannot copy image file %r: %s' %
|
logger.warning('cannot copy image file %r: %s',
|
||||||
(path.join(self.srcdir, src), err))
|
path.join(self.srcdir, src), err)
|
||||||
|
|
||||||
def copy_download_files(self):
|
def copy_download_files(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
@ -614,8 +614,8 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
copyfile(path.join(self.srcdir, src),
|
copyfile(path.join(self.srcdir, src),
|
||||||
path.join(self.outdir, '_downloads', dest))
|
path.join(self.outdir, '_downloads', dest))
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.warn('cannot copy downloadable file %r: %s' %
|
logger.warning('cannot copy downloadable file %r: %s',
|
||||||
(path.join(self.srcdir, src), err))
|
path.join(self.srcdir, src), err)
|
||||||
|
|
||||||
def copy_static_files(self):
|
def copy_static_files(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
@ -655,7 +655,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
for static_path in self.config.html_static_path:
|
for static_path in self.config.html_static_path:
|
||||||
entry = path.join(self.confdir, static_path)
|
entry = path.join(self.confdir, static_path)
|
||||||
if not path.exists(entry):
|
if not path.exists(entry):
|
||||||
self.warn('html_static_path entry %r does not exist' % entry)
|
logger.warning('html_static_path entry %r does not exist', entry)
|
||||||
continue
|
continue
|
||||||
copy_asset(entry, path.join(self.outdir, '_static'), excluded,
|
copy_asset(entry, path.join(self.outdir, '_static'), excluded,
|
||||||
context=ctx, renderer=self.templates)
|
context=ctx, renderer=self.templates)
|
||||||
@ -664,7 +664,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
logobase = path.basename(self.config.html_logo)
|
logobase = path.basename(self.config.html_logo)
|
||||||
logotarget = path.join(self.outdir, '_static', logobase)
|
logotarget = path.join(self.outdir, '_static', logobase)
|
||||||
if not path.isfile(path.join(self.confdir, self.config.html_logo)):
|
if not path.isfile(path.join(self.confdir, self.config.html_logo)):
|
||||||
self.warn('logo file %r does not exist' % self.config.html_logo)
|
logger.warning('logo file %r does not exist', self.config.html_logo)
|
||||||
elif not path.isfile(logotarget):
|
elif not path.isfile(logotarget):
|
||||||
copyfile(path.join(self.confdir, self.config.html_logo),
|
copyfile(path.join(self.confdir, self.config.html_logo),
|
||||||
logotarget)
|
logotarget)
|
||||||
@ -672,7 +672,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
iconbase = path.basename(self.config.html_favicon)
|
iconbase = path.basename(self.config.html_favicon)
|
||||||
icontarget = path.join(self.outdir, '_static', iconbase)
|
icontarget = path.join(self.outdir, '_static', iconbase)
|
||||||
if not path.isfile(path.join(self.confdir, self.config.html_favicon)):
|
if not path.isfile(path.join(self.confdir, self.config.html_favicon)):
|
||||||
self.warn('favicon file %r does not exist' % self.config.html_favicon)
|
logger.warning('favicon file %r does not exist', self.config.html_favicon)
|
||||||
elif not path.isfile(icontarget):
|
elif not path.isfile(icontarget):
|
||||||
copyfile(path.join(self.confdir, self.config.html_favicon),
|
copyfile(path.join(self.confdir, self.config.html_favicon),
|
||||||
icontarget)
|
icontarget)
|
||||||
@ -687,7 +687,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
for extra_path in self.config.html_extra_path:
|
for extra_path in self.config.html_extra_path:
|
||||||
entry = path.join(self.confdir, extra_path)
|
entry = path.join(self.confdir, extra_path)
|
||||||
if not path.exists(entry):
|
if not path.exists(entry):
|
||||||
self.warn('html_extra_path entry %r does not exist' % entry)
|
logger.warning('html_extra_path entry %r does not exist', entry)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
copy_asset(entry, self.outdir, excluded)
|
copy_asset(entry, self.outdir, excluded)
|
||||||
@ -748,9 +748,9 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
self.indexer.load(f, self.indexer_format) # type: ignore
|
self.indexer.load(f, self.indexer_format) # type: ignore
|
||||||
except (IOError, OSError, ValueError):
|
except (IOError, OSError, ValueError):
|
||||||
if keep:
|
if keep:
|
||||||
self.warn('search index couldn\'t be loaded, but not all '
|
logger.warning('search index couldn\'t be loaded, but not all '
|
||||||
'documents will be built: the index will be '
|
'documents will be built: the index will be '
|
||||||
'incomplete.')
|
'incomplete.')
|
||||||
# delete all entries for files that will be rebuilt
|
# delete all entries for files that will be rebuilt
|
||||||
self.indexer.prune(keep)
|
self.indexer.prune(keep)
|
||||||
|
|
||||||
@ -789,9 +789,9 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
if has_wildcard(pattern):
|
if has_wildcard(pattern):
|
||||||
# warn if both patterns contain wildcards
|
# warn if both patterns contain wildcards
|
||||||
if has_wildcard(matched):
|
if has_wildcard(matched):
|
||||||
self.warn('page %s matches two patterns in '
|
logger.warning('page %s matches two patterns in '
|
||||||
'html_sidebars: %r and %r' %
|
'html_sidebars: %r and %r',
|
||||||
(pagename, matched, pattern))
|
pagename, matched, pattern)
|
||||||
# else the already matched pattern is more specific
|
# else the already matched pattern is more specific
|
||||||
# than the present one, because it contains no wildcard
|
# than the present one, because it contains no wildcard
|
||||||
continue
|
continue
|
||||||
@ -863,9 +863,9 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
try:
|
try:
|
||||||
output = self.templates.render(templatename, ctx)
|
output = self.templates.render(templatename, ctx)
|
||||||
except UnicodeError:
|
except UnicodeError:
|
||||||
self.warn("a Unicode error occurred when rendering the page %s. "
|
logger.warning("a Unicode error occurred when rendering the page %s. "
|
||||||
"Please make sure all config values that contain "
|
"Please make sure all config values that contain "
|
||||||
"non-ASCII content are Unicode strings." % pagename)
|
"non-ASCII content are Unicode strings.", pagename)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not outfilename:
|
if not outfilename:
|
||||||
@ -876,7 +876,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
with codecs.open(outfilename, 'w', encoding, 'xmlcharrefreplace') as f: # type: ignore # NOQA
|
with codecs.open(outfilename, 'w', encoding, 'xmlcharrefreplace') as f: # type: ignore # NOQA
|
||||||
f.write(output)
|
f.write(output)
|
||||||
except (IOError, OSError) as err:
|
except (IOError, OSError) as err:
|
||||||
self.warn("error writing file %s: %s" % (outfilename, err))
|
logger.warning("error writing file %s: %s", outfilename, err)
|
||||||
if self.copysource and ctx.get('sourcename'):
|
if self.copysource and ctx.get('sourcename'):
|
||||||
# copy the source file for the "show source" link
|
# copy the source file for the "show source" link
|
||||||
source_name = path.join(self.outdir, '_sources',
|
source_name = path.join(self.outdir, '_sources',
|
||||||
@ -1270,8 +1270,8 @@ class JSONHTMLBuilder(SerializingHTMLBuilder):
|
|||||||
def validate_config_values(app):
|
def validate_config_values(app):
|
||||||
# type: (Sphinx) -> None
|
# type: (Sphinx) -> None
|
||||||
if app.config.html_translator_class:
|
if app.config.html_translator_class:
|
||||||
app.warn('html_translator_class is deprecated. '
|
logger.warning('html_translator_class is deprecated. '
|
||||||
'Use Sphinx.set_translator() API instead.')
|
'Use Sphinx.set_translator() API instead.')
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
|
@ -76,16 +76,16 @@ class LaTeXBuilder(Builder):
|
|||||||
# type: () -> None
|
# type: () -> None
|
||||||
preliminary_document_data = [list(x) for x in self.config.latex_documents]
|
preliminary_document_data = [list(x) for x in self.config.latex_documents]
|
||||||
if not preliminary_document_data:
|
if not preliminary_document_data:
|
||||||
self.warn('no "latex_documents" config value found; no documents '
|
logger.warning('no "latex_documents" config value found; no documents '
|
||||||
'will be written')
|
'will be written')
|
||||||
return
|
return
|
||||||
# assign subdirs to titles
|
# assign subdirs to titles
|
||||||
self.titles = [] # type: List[Tuple[unicode, unicode]]
|
self.titles = [] # type: List[Tuple[unicode, unicode]]
|
||||||
for entry in preliminary_document_data:
|
for entry in preliminary_document_data:
|
||||||
docname = entry[0]
|
docname = entry[0]
|
||||||
if docname not in self.env.all_docs:
|
if docname not in self.env.all_docs:
|
||||||
self.warn('"latex_documents" config value references unknown '
|
logger.warning('"latex_documents" config value references unknown '
|
||||||
'document %s' % docname)
|
'document %s', docname)
|
||||||
continue
|
continue
|
||||||
self.document_data.append(entry) # type: ignore
|
self.document_data.append(entry) # type: ignore
|
||||||
if docname.endswith(SEP+'index'):
|
if docname.endswith(SEP+'index'):
|
||||||
@ -241,50 +241,58 @@ class LaTeXBuilder(Builder):
|
|||||||
def validate_config_values(app):
|
def validate_config_values(app):
|
||||||
# type: (Sphinx) -> None
|
# type: (Sphinx) -> None
|
||||||
if app.config.latex_toplevel_sectioning not in (None, 'part', 'chapter', 'section'):
|
if app.config.latex_toplevel_sectioning not in (None, 'part', 'chapter', 'section'):
|
||||||
app.warn('invalid latex_toplevel_sectioning, ignored: %s' %
|
logger.warning('invalid latex_toplevel_sectioning, ignored: %s' %
|
||||||
app.config.latex_toplevel_sectioning)
|
app.config.latex_toplevel_sectioning)
|
||||||
app.config.latex_toplevel_sectioning = None # type: ignore
|
app.config.latex_toplevel_sectioning = None # type: ignore
|
||||||
|
|
||||||
if app.config.latex_use_parts:
|
if app.config.latex_use_parts:
|
||||||
if app.config.latex_toplevel_sectioning:
|
if app.config.latex_toplevel_sectioning:
|
||||||
app.warn('latex_use_parts conflicts with latex_toplevel_sectioning, ignored.')
|
logger.warning('latex_use_parts conflicts with '
|
||||||
|
'latex_toplevel_sectioning, ignored.')
|
||||||
else:
|
else:
|
||||||
app.warn('latex_use_parts is deprecated. Use latex_toplevel_sectioning instead.')
|
logger.warning('latex_use_parts is deprecated. '
|
||||||
|
'Use latex_toplevel_sectioning instead.')
|
||||||
app.config.latex_toplevel_sectioning = 'part' # type: ignore
|
app.config.latex_toplevel_sectioning = 'part' # type: ignore
|
||||||
|
|
||||||
if app.config.latex_use_modindex is not True: # changed by user
|
if app.config.latex_use_modindex is not True: # changed by user
|
||||||
app.warn('latex_use_modindex is deprecated. Use latex_domain_indices instead.')
|
logger.warning('latex_use_modindex is deprecated. '
|
||||||
|
'Use latex_domain_indices instead.')
|
||||||
|
|
||||||
if app.config.latex_preamble:
|
if app.config.latex_preamble:
|
||||||
if app.config.latex_elements.get('preamble'):
|
if app.config.latex_elements.get('preamble'):
|
||||||
app.warn("latex_preamble conflicts with latex_elements['preamble'], ignored.")
|
logger.warning("latex_preamble conflicts with "
|
||||||
|
"latex_elements['preamble'], ignored.")
|
||||||
else:
|
else:
|
||||||
app.warn("latex_preamble is deprecated. Use latex_elements['preamble'] instead.")
|
logger.warning("latex_preamble is deprecated. "
|
||||||
|
"Use latex_elements['preamble'] instead.")
|
||||||
app.config.latex_elements['preamble'] = app.config.latex_preamble
|
app.config.latex_elements['preamble'] = app.config.latex_preamble
|
||||||
|
|
||||||
if app.config.latex_paper_size != 'letter':
|
if app.config.latex_paper_size != 'letter':
|
||||||
if app.config.latex_elements.get('papersize'):
|
if app.config.latex_elements.get('papersize'):
|
||||||
app.warn("latex_paper_size conflicts with latex_elements['papersize'], ignored.")
|
logger.warning("latex_paper_size conflicts with "
|
||||||
|
"latex_elements['papersize'], ignored.")
|
||||||
else:
|
else:
|
||||||
app.warn("latex_paper_size is deprecated. "
|
logger.warning("latex_paper_size is deprecated. "
|
||||||
"Use latex_elements['papersize'] instead.")
|
"Use latex_elements['papersize'] instead.")
|
||||||
if app.config.latex_paper_size:
|
if app.config.latex_paper_size:
|
||||||
app.config.latex_elements['papersize'] = app.config.latex_paper_size + 'paper'
|
app.config.latex_elements['papersize'] = app.config.latex_paper_size + 'paper'
|
||||||
|
|
||||||
if app.config.latex_font_size != '10pt':
|
if app.config.latex_font_size != '10pt':
|
||||||
if app.config.latex_elements.get('pointsize'):
|
if app.config.latex_elements.get('pointsize'):
|
||||||
app.warn("latex_font_size conflicts with latex_elements['pointsize'], ignored.")
|
logger.warning("latex_font_size conflicts with "
|
||||||
|
"latex_elements['pointsize'], ignored.")
|
||||||
else:
|
else:
|
||||||
app.warn("latex_font_size is deprecated. Use latex_elements['pointsize'] instead.")
|
logger.warning("latex_font_size is deprecated. "
|
||||||
|
"Use latex_elements['pointsize'] instead.")
|
||||||
app.config.latex_elements['pointsize'] = app.config.latex_font_size
|
app.config.latex_elements['pointsize'] = app.config.latex_font_size
|
||||||
|
|
||||||
if 'footer' in app.config.latex_elements:
|
if 'footer' in app.config.latex_elements:
|
||||||
if 'postamble' in app.config.latex_elements:
|
if 'postamble' in app.config.latex_elements:
|
||||||
app.warn("latex_elements['footer'] conflicts with "
|
logger.warning("latex_elements['footer'] conflicts with "
|
||||||
"latex_elements['postamble'], ignored.")
|
"latex_elements['postamble'], ignored.")
|
||||||
else:
|
else:
|
||||||
app.warn("latex_elements['footer'] is deprecated. "
|
logger.warning("latex_elements['footer'] is deprecated. "
|
||||||
"Use latex_elements['preamble'] instead.")
|
"Use latex_elements['preamble'] instead.")
|
||||||
app.config.latex_elements['postamble'] = app.config.latex_elements['footer']
|
app.config.latex_elements['postamble'] = app.config.latex_elements['footer']
|
||||||
|
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
if status == 'working' and info == 'old':
|
if status == 'working' and info == 'old':
|
||||||
return
|
return
|
||||||
if lineno:
|
if lineno:
|
||||||
logger.info('(line %4d) ' % lineno, nonl=1)
|
logger.info('(line %4d) ', lineno, nonl=1)
|
||||||
if status == 'ignored':
|
if status == 'ignored':
|
||||||
if info:
|
if info:
|
||||||
logger.info(darkgray('-ignored- ') + uri + ': ' + info)
|
logger.info(darkgray('-ignored- ') + uri + ': ' + info)
|
||||||
@ -247,8 +247,8 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
elif status == 'broken':
|
elif status == 'broken':
|
||||||
self.write_entry('broken', docname, lineno, uri + ': ' + info)
|
self.write_entry('broken', docname, lineno, uri + ': ' + info)
|
||||||
if self.app.quiet or self.app.warningiserror:
|
if self.app.quiet or self.app.warningiserror:
|
||||||
self.warn('broken link: %s (%s)' % (uri, info),
|
logger.warning('broken link: %s (%s)', uri, info,
|
||||||
'%s:%s' % (self.env.doc2path(docname), lineno))
|
location=(self.env.doc2path(docname), lineno))
|
||||||
else:
|
else:
|
||||||
logger.info(red('broken ') + uri + red(' - ' + info))
|
logger.info(red('broken ') + uri + red(' - ' + info))
|
||||||
elif status == 'redirected':
|
elif status == 'redirected':
|
||||||
|
@ -45,8 +45,8 @@ class ManualPageBuilder(Builder):
|
|||||||
def init(self):
|
def init(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
if not self.config.man_pages:
|
if not self.config.man_pages:
|
||||||
self.warn('no "man_pages" config value found; no manual pages '
|
logger.warning('no "man_pages" config value found; no manual pages '
|
||||||
'will be written')
|
'will be written')
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self):
|
||||||
# type: () -> Union[unicode, List[unicode]]
|
# type: () -> Union[unicode, List[unicode]]
|
||||||
|
@ -124,16 +124,16 @@ class TexinfoBuilder(Builder):
|
|||||||
# type: () -> None
|
# type: () -> None
|
||||||
preliminary_document_data = [list(x) for x in self.config.texinfo_documents]
|
preliminary_document_data = [list(x) for x in self.config.texinfo_documents]
|
||||||
if not preliminary_document_data:
|
if not preliminary_document_data:
|
||||||
self.warn('no "texinfo_documents" config value found; no documents '
|
logger.warning('no "texinfo_documents" config value found; no documents '
|
||||||
'will be written')
|
'will be written')
|
||||||
return
|
return
|
||||||
# assign subdirs to titles
|
# assign subdirs to titles
|
||||||
self.titles = [] # type: List[Tuple[unicode, unicode]]
|
self.titles = [] # type: List[Tuple[unicode, unicode]]
|
||||||
for entry in preliminary_document_data:
|
for entry in preliminary_document_data:
|
||||||
docname = entry[0]
|
docname = entry[0]
|
||||||
if docname not in self.env.all_docs:
|
if docname not in self.env.all_docs:
|
||||||
self.warn('"texinfo_documents" config value references unknown '
|
logger.warning('"texinfo_documents" config value references unknown '
|
||||||
'document %s' % docname)
|
'document %s', docname)
|
||||||
continue
|
continue
|
||||||
self.document_data.append(entry) # type: ignore
|
self.document_data.append(entry) # type: ignore
|
||||||
if docname.endswith(SEP+'index'):
|
if docname.endswith(SEP+'index'):
|
||||||
@ -240,7 +240,7 @@ class TexinfoBuilder(Builder):
|
|||||||
with open(fn, 'w') as mkfile:
|
with open(fn, 'w') as mkfile:
|
||||||
mkfile.write(TEXINFO_MAKEFILE)
|
mkfile.write(TEXINFO_MAKEFILE)
|
||||||
except (IOError, OSError) as err:
|
except (IOError, OSError) as err:
|
||||||
self.warn("error writing file %s: %s" % (fn, err))
|
logger.warning("error writing file %s: %s", fn, err)
|
||||||
logger.info(' done')
|
logger.info(' done')
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,9 +15,12 @@ from os import path
|
|||||||
from docutils.io import StringOutput
|
from docutils.io import StringOutput
|
||||||
|
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
|
from sphinx.util import logging
|
||||||
from sphinx.util.osutil import ensuredir, os_path
|
from sphinx.util.osutil import ensuredir, os_path
|
||||||
from sphinx.writers.text import TextWriter
|
from sphinx.writers.text import TextWriter
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class TextBuilder(Builder):
|
class TextBuilder(Builder):
|
||||||
name = 'text'
|
name = 'text'
|
||||||
@ -65,7 +68,7 @@ class TextBuilder(Builder):
|
|||||||
with codecs.open(outfilename, 'w', 'utf-8') as f:
|
with codecs.open(outfilename, 'w', 'utf-8') as f:
|
||||||
f.write(self.writer.output)
|
f.write(self.writer.output)
|
||||||
except (IOError, OSError) as err:
|
except (IOError, OSError) as err:
|
||||||
self.warn("error writing file %s: %s" % (outfilename, err))
|
logger.warning("error writing file %s: %s", outfilename, err)
|
||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
pass
|
pass
|
||||||
|
@ -16,9 +16,12 @@ from docutils import nodes
|
|||||||
from docutils.io import StringOutput
|
from docutils.io import StringOutput
|
||||||
|
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
|
from sphinx.util import logging
|
||||||
from sphinx.util.osutil import ensuredir, os_path
|
from sphinx.util.osutil import ensuredir, os_path
|
||||||
from sphinx.writers.xml import XMLWriter, PseudoXMLWriter
|
from sphinx.writers.xml import XMLWriter, PseudoXMLWriter
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class XMLBuilder(Builder):
|
class XMLBuilder(Builder):
|
||||||
"""
|
"""
|
||||||
@ -80,7 +83,7 @@ class XMLBuilder(Builder):
|
|||||||
with codecs.open(outfilename, 'w', 'utf-8') as f:
|
with codecs.open(outfilename, 'w', 'utf-8') as f:
|
||||||
f.write(self.writer.output)
|
f.write(self.writer.output)
|
||||||
except (IOError, OSError) as err:
|
except (IOError, OSError) as err:
|
||||||
self.warn("error writing file %s: %s" % (outfilename, err))
|
logger.warning("error writing file %s: %s", outfilename, err)
|
||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
pass
|
pass
|
||||||
|
@ -219,7 +219,7 @@ class Config(object):
|
|||||||
if isinstance(value, binary_type) and nonascii_re.search(value): # type: ignore
|
if isinstance(value, binary_type) and nonascii_re.search(value): # type: ignore
|
||||||
logger.warning('the config value %r is set to a string with non-ASCII '
|
logger.warning('the config value %r is set to a string with non-ASCII '
|
||||||
'characters; this can lead to Unicode errors occurring. '
|
'characters; this can lead to Unicode errors occurring. '
|
||||||
'Please use Unicode strings, e.g. %r.' % (name, u'Content'))
|
'Please use Unicode strings, e.g. %r.', name, u'Content')
|
||||||
|
|
||||||
def convert_overrides(self, name, value):
|
def convert_overrides(self, name, value):
|
||||||
# type: (unicode, Any) -> Any
|
# type: (unicode, Any) -> Any
|
||||||
@ -258,7 +258,7 @@ class Config(object):
|
|||||||
elif name in self._raw_config:
|
elif name in self._raw_config:
|
||||||
self.__dict__[name] = self._raw_config[name]
|
self.__dict__[name] = self._raw_config[name]
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
logger.warning("%s" % exc)
|
logger.warning("%s", exc)
|
||||||
|
|
||||||
def init_values(self):
|
def init_values(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
@ -270,14 +270,14 @@ class Config(object):
|
|||||||
config.setdefault(realvalname, {})[key] = value # type: ignore
|
config.setdefault(realvalname, {})[key] = value # type: ignore
|
||||||
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)
|
||||||
else:
|
else:
|
||||||
config[valname] = value
|
config[valname] = value
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
logger.warning("%s" % exc)
|
logger.warning("%s", exc)
|
||||||
for name in config:
|
for name in config:
|
||||||
if name in self.values:
|
if name in self.values:
|
||||||
self.__dict__[name] = config[name]
|
self.__dict__[name] = config[name]
|
||||||
|
@ -22,6 +22,7 @@ from sphinx.roles import XRefRole
|
|||||||
from sphinx.locale import l_, _
|
from sphinx.locale import l_, _
|
||||||
from sphinx.domains import Domain, ObjType
|
from sphinx.domains import Domain, ObjType
|
||||||
from sphinx.directives import ObjectDescription
|
from sphinx.directives import ObjectDescription
|
||||||
|
from sphinx.util import logging
|
||||||
from sphinx.util.nodes import make_refnode
|
from sphinx.util.nodes import make_refnode
|
||||||
from sphinx.util.pycompat import UnicodeMixin
|
from sphinx.util.pycompat import UnicodeMixin
|
||||||
from sphinx.util.docfields import Field, GroupedField
|
from sphinx.util.docfields import Field, GroupedField
|
||||||
@ -34,6 +35,8 @@ if False:
|
|||||||
from sphinx.config import Config # NOQA
|
from sphinx.config import Config # NOQA
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
from sphinx.environment import BuildEnvironment # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Important note on ids
|
Important note on ids
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
@ -3060,7 +3063,7 @@ class Symbol(object):
|
|||||||
msg = "Duplicate declaration, also defined in '%s'.\n"
|
msg = "Duplicate declaration, also defined in '%s'.\n"
|
||||||
msg += "Declaration is '%s'."
|
msg += "Declaration is '%s'."
|
||||||
msg = msg % (ourChild.docname, name)
|
msg = msg % (ourChild.docname, name)
|
||||||
env.warn(otherChild.docname, msg)
|
logger.warning(msg, location=otherChild.docname)
|
||||||
else:
|
else:
|
||||||
# Both have declarations, and in the same docname.
|
# Both have declarations, and in the same docname.
|
||||||
# This can apparently happen, it should be safe to
|
# This can apparently happen, it should be safe to
|
||||||
@ -4872,7 +4875,7 @@ class CPPDomain(Domain):
|
|||||||
msg = "Duplicate declaration, also defined in '%s'.\n"
|
msg = "Duplicate declaration, also defined in '%s'.\n"
|
||||||
msg += "Name of declaration is '%s'."
|
msg += "Name of declaration is '%s'."
|
||||||
msg = msg % (ourNames[name], name)
|
msg = msg % (ourNames[name], name)
|
||||||
self.env.warn(docname, msg)
|
logger.warning(msg, docname)
|
||||||
else:
|
else:
|
||||||
ourNames[name] = docname
|
ourNames[name] = docname
|
||||||
|
|
||||||
@ -4882,7 +4885,7 @@ class CPPDomain(Domain):
|
|||||||
class Warner(object):
|
class Warner(object):
|
||||||
def warn(self, msg):
|
def warn(self, msg):
|
||||||
if emitWarnings:
|
if emitWarnings:
|
||||||
env.warn_node(msg, node)
|
logger.warn_node(msg, node)
|
||||||
warner = Warner()
|
warner = Warner()
|
||||||
parser = DefinitionParser(target, warner, env.config)
|
parser = DefinitionParser(target, warner, env.config)
|
||||||
try:
|
try:
|
||||||
|
@ -21,6 +21,7 @@ from sphinx.roles import XRefRole
|
|||||||
from sphinx.locale import l_, _
|
from sphinx.locale import l_, _
|
||||||
from sphinx.domains import Domain, ObjType, Index
|
from sphinx.domains import Domain, ObjType, Index
|
||||||
from sphinx.directives import ObjectDescription
|
from sphinx.directives import ObjectDescription
|
||||||
|
from sphinx.util import logging
|
||||||
from sphinx.util.nodes import make_refnode
|
from sphinx.util.nodes import make_refnode
|
||||||
from sphinx.util.docfields import Field, GroupedField, TypedField
|
from sphinx.util.docfields import Field, GroupedField, TypedField
|
||||||
|
|
||||||
@ -31,6 +32,8 @@ if False:
|
|||||||
from sphinx.builders import Builder # NOQA
|
from sphinx.builders import Builder # NOQA
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
from sphinx.environment import BuildEnvironment # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# REs for Python signatures
|
# REs for Python signatures
|
||||||
py_sig_re = re.compile(
|
py_sig_re = re.compile(
|
||||||
@ -784,7 +787,7 @@ class PythonDomain(Domain):
|
|||||||
if not matches:
|
if not matches:
|
||||||
return None
|
return None
|
||||||
elif len(matches) > 1:
|
elif len(matches) > 1:
|
||||||
env.warn_node(
|
logger.warn_node(
|
||||||
'more than one target found for cross-reference '
|
'more than one target found for cross-reference '
|
||||||
'%r: %s' % (target, ', '.join(match[0] for match in matches)),
|
'%r: %s' % (target, ', '.join(match[0] for match in matches)),
|
||||||
node)
|
node)
|
||||||
|
@ -23,7 +23,7 @@ from sphinx.roles import XRefRole
|
|||||||
from sphinx.locale import l_, _
|
from sphinx.locale import l_, _
|
||||||
from sphinx.domains import Domain, ObjType
|
from sphinx.domains import Domain, ObjType
|
||||||
from sphinx.directives import ObjectDescription
|
from sphinx.directives import ObjectDescription
|
||||||
from sphinx.util import ws_re
|
from sphinx.util import ws_re, logging
|
||||||
from sphinx.util.nodes import clean_astext, make_refnode
|
from sphinx.util.nodes import clean_astext, make_refnode
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
@ -41,6 +41,8 @@ if False:
|
|||||||
RoleFunction = Callable[[unicode, unicode, unicode, int, Inliner, Dict, List[unicode]],
|
RoleFunction = Callable[[unicode, unicode, unicode, int, Inliner, Dict, List[unicode]],
|
||||||
Tuple[List[nodes.Node], List[nodes.Node]]]
|
Tuple[List[nodes.Node], List[nodes.Node]]]
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# RE for option descriptions
|
# RE for option descriptions
|
||||||
option_desc_re = re.compile(r'((?:/|--|-|\+)?[-\.?@#_a-zA-Z0-9]+)(=?\s*.*)')
|
option_desc_re = re.compile(r'((?:/|--|-|\+)?[-\.?@#_a-zA-Z0-9]+)(=?\s*.*)')
|
||||||
@ -163,12 +165,10 @@ class Cmdoption(ObjectDescription):
|
|||||||
potential_option = potential_option.strip()
|
potential_option = potential_option.strip()
|
||||||
m = option_desc_re.match(potential_option) # type: ignore
|
m = option_desc_re.match(potential_option) # type: ignore
|
||||||
if not m:
|
if not m:
|
||||||
self.env.warn(
|
logger.warning('Malformed option description %r, should '
|
||||||
self.env.docname,
|
'look like "opt", "-opt args", "--opt args", '
|
||||||
'Malformed option description %r, should '
|
'"/opt args" or "+opt args"', potential_option,
|
||||||
'look like "opt", "-opt args", "--opt args", '
|
location=(self.env.docname, self.lineno))
|
||||||
'"/opt args" or "+opt args"' % potential_option,
|
|
||||||
self.lineno)
|
|
||||||
continue
|
continue
|
||||||
optname, args = m.groups()
|
optname, args = m.groups()
|
||||||
if count:
|
if count:
|
||||||
@ -573,8 +573,8 @@ class StandardDomain(Domain):
|
|||||||
label = node[0].astext()
|
label = node[0].astext()
|
||||||
if label in self.data['citations']:
|
if label in self.data['citations']:
|
||||||
path = env.doc2path(self.data['citations'][label][0])
|
path = env.doc2path(self.data['citations'][label][0])
|
||||||
env.warn_node('duplicate citation %s, other instance in %s' %
|
logger.warn_node('duplicate citation %s, other instance in %s' %
|
||||||
(label, path), node)
|
(label, path), node)
|
||||||
self.data['citations'][label] = (docname, node['ids'][0])
|
self.data['citations'][label] = (docname, node['ids'][0])
|
||||||
|
|
||||||
def note_labels(self, env, docname, document):
|
def note_labels(self, env, docname, document):
|
||||||
@ -596,8 +596,8 @@ class StandardDomain(Domain):
|
|||||||
# link and object descriptions
|
# link and object descriptions
|
||||||
continue
|
continue
|
||||||
if name in labels:
|
if name in labels:
|
||||||
env.warn_node('duplicate label %s, ' % name + 'other instance '
|
logger.warn_node('duplicate label %s, ' % name + 'other instance '
|
||||||
'in ' + env.doc2path(labels[name][0]), node)
|
'in ' + env.doc2path(labels[name][0]), node)
|
||||||
anonlabels[name] = docname, labelid
|
anonlabels[name] = docname, labelid
|
||||||
if node.tagname == 'section':
|
if node.tagname == 'section':
|
||||||
sectname = clean_astext(node[0]) # node[0] == title node
|
sectname = clean_astext(node[0]) # node[0] == title node
|
||||||
@ -688,7 +688,7 @@ class StandardDomain(Domain):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
if env.config.numfig is False:
|
if env.config.numfig is False:
|
||||||
env.warn_node('numfig is disabled. :numref: is ignored.', node)
|
logger.warn_node('numfig is disabled. :numref: is ignored.', node)
|
||||||
return contnode
|
return contnode
|
||||||
|
|
||||||
target_node = env.get_doctree(docname).ids.get(labelid)
|
target_node = env.get_doctree(docname).ids.get(labelid)
|
||||||
@ -701,7 +701,7 @@ class StandardDomain(Domain):
|
|||||||
if fignumber is None:
|
if fignumber is None:
|
||||||
return contnode
|
return contnode
|
||||||
except ValueError:
|
except ValueError:
|
||||||
env.warn_node("no number is assigned for %s: %s" % (figtype, labelid), node)
|
logger.warn_node("no number is assigned for %s: %s" % (figtype, labelid), node)
|
||||||
return contnode
|
return contnode
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -711,7 +711,7 @@ class StandardDomain(Domain):
|
|||||||
title = env.config.numfig_format.get(figtype, '')
|
title = env.config.numfig_format.get(figtype, '')
|
||||||
|
|
||||||
if figname is None and '%{name}' in title:
|
if figname is None and '%{name}' in title:
|
||||||
env.warn_node('the link has no caption: %s' % title, node)
|
logger.warn_node('the link has no caption: %s' % title, node)
|
||||||
return contnode
|
return contnode
|
||||||
else:
|
else:
|
||||||
fignum = '.'.join(map(str, fignumber))
|
fignum = '.'.join(map(str, fignumber))
|
||||||
@ -725,10 +725,10 @@ class StandardDomain(Domain):
|
|||||||
# old style format (cf. "Fig.%s")
|
# old style format (cf. "Fig.%s")
|
||||||
newtitle = title % fignum
|
newtitle = title % fignum
|
||||||
except KeyError as exc:
|
except KeyError as exc:
|
||||||
env.warn_node('invalid numfig_format: %s (%r)' % (title, exc), node)
|
logger.warn_node('invalid numfig_format: %s (%r)' % (title, exc), node)
|
||||||
return contnode
|
return contnode
|
||||||
except TypeError:
|
except TypeError:
|
||||||
env.warn_node('invalid numfig_format: %s' % title, node)
|
logger.warn_node('invalid numfig_format: %s' % title, node)
|
||||||
return contnode
|
return contnode
|
||||||
|
|
||||||
return self.build_reference_node(fromdocname, builder,
|
return self.build_reference_node(fromdocname, builder,
|
||||||
|
@ -447,7 +447,7 @@ class BuildEnvironment(object):
|
|||||||
if os.access(self.doc2path(docname), os.R_OK):
|
if os.access(self.doc2path(docname), os.R_OK):
|
||||||
self.found_docs.add(docname)
|
self.found_docs.add(docname)
|
||||||
else:
|
else:
|
||||||
self.warn(docname, "document not readable. Ignored.")
|
logger.warning("document not readable. Ignored.", location=docname)
|
||||||
|
|
||||||
# Current implementation is applying translated messages in the reading
|
# Current implementation is applying translated messages in the reading
|
||||||
# phase.Therefore, in order to apply the updated message catalog, it is
|
# phase.Therefore, in order to apply the updated message catalog, it is
|
||||||
@ -594,14 +594,14 @@ class BuildEnvironment(object):
|
|||||||
if ext_ok:
|
if ext_ok:
|
||||||
continue
|
continue
|
||||||
if ext_ok is None:
|
if ext_ok is None:
|
||||||
app.warn('the %s extension does not declare if it '
|
logger.warning('the %s extension does not declare if it '
|
||||||
'is safe for parallel reading, assuming it '
|
'is safe for parallel reading, assuming it '
|
||||||
'isn\'t - please ask the extension author to '
|
'isn\'t - please ask the extension author to '
|
||||||
'check and make it explicit' % extname)
|
'check and make it explicit', extname)
|
||||||
app.warn('doing serial read')
|
logger.warning('doing serial read')
|
||||||
else:
|
else:
|
||||||
app.warn('the %s extension is not safe for parallel '
|
logger.warning('the %s extension is not safe for parallel '
|
||||||
'reading, doing serial read' % extname)
|
'reading, doing serial read', extname)
|
||||||
par_ok = False
|
par_ok = False
|
||||||
break
|
break
|
||||||
if par_ok:
|
if par_ok:
|
||||||
@ -690,11 +690,11 @@ class BuildEnvironment(object):
|
|||||||
if lineend == -1:
|
if lineend == -1:
|
||||||
lineend = len(error.object)
|
lineend = len(error.object)
|
||||||
lineno = error.object.count(b'\n', 0, error.start) + 1
|
lineno = error.object.count(b'\n', 0, error.start) + 1
|
||||||
self.warn(self.docname, 'undecodable source characters, '
|
logger.warning('undecodable source characters, replacing with "?": %r',
|
||||||
'replacing with "?": %r' %
|
(error.object[linestart+1:error.start] + b'>>>' +
|
||||||
(error.object[linestart+1:error.start] + b'>>>' +
|
error.object[error.start:error.end] + b'<<<' +
|
||||||
error.object[error.start:error.end] + b'<<<' +
|
error.object[error.end:lineend]),
|
||||||
error.object[error.end:lineend]), lineno)
|
location=(self.docname, lineno))
|
||||||
return (u'?', error.end)
|
return (u'?', error.end)
|
||||||
|
|
||||||
def read_doc(self, docname, app=None):
|
def read_doc(self, docname, app=None):
|
||||||
@ -724,8 +724,8 @@ class BuildEnvironment(object):
|
|||||||
if role_fn:
|
if role_fn:
|
||||||
roles._roles[''] = role_fn
|
roles._roles[''] = role_fn
|
||||||
else:
|
else:
|
||||||
self.warn(docname, 'default role %s not found' %
|
logger.warning('default role %s not found', self.config.default_role,
|
||||||
self.config.default_role)
|
location=docname)
|
||||||
|
|
||||||
codecs.register_error('sphinx', self.warn_and_replace) # type: ignore
|
codecs.register_error('sphinx', self.warn_and_replace) # type: ignore
|
||||||
|
|
||||||
@ -816,16 +816,18 @@ class BuildEnvironment(object):
|
|||||||
def currmodule(self):
|
def currmodule(self):
|
||||||
# type () -> None
|
# type () -> None
|
||||||
"""Backwards compatible alias. Will be removed."""
|
"""Backwards compatible alias. Will be removed."""
|
||||||
self.warn(self.docname, 'env.currmodule is being referenced by an '
|
logger.warning('env.currmodule is being referenced by an '
|
||||||
'extension; this API will be removed in the future')
|
'extension; this API will be removed in the future',
|
||||||
|
location=self.docname)
|
||||||
return self.ref_context.get('py:module')
|
return self.ref_context.get('py:module')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def currclass(self):
|
def currclass(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
"""Backwards compatible alias. Will be removed."""
|
"""Backwards compatible alias. Will be removed."""
|
||||||
self.warn(self.docname, 'env.currclass is being referenced by an '
|
logger.warning('env.currclass is being referenced by an '
|
||||||
'extension; this API will be removed in the future')
|
'extension; this API will be removed in the future',
|
||||||
|
location=self.docname)
|
||||||
return self.ref_context.get('py:class')
|
return self.ref_context.get('py:class')
|
||||||
|
|
||||||
def new_serialno(self, category=''):
|
def new_serialno(self, category=''):
|
||||||
@ -900,8 +902,8 @@ class BuildEnvironment(object):
|
|||||||
rel_filename, filename = self.relfn2path(targetname, docname)
|
rel_filename, filename = self.relfn2path(targetname, docname)
|
||||||
self.dependencies[docname].add(rel_filename)
|
self.dependencies[docname].add(rel_filename)
|
||||||
if not os.access(filename, os.R_OK):
|
if not os.access(filename, os.R_OK):
|
||||||
self.warn_node('download file not readable: %s' % filename,
|
logger.warn_node('download file not readable: %s' % filename,
|
||||||
node)
|
node)
|
||||||
continue
|
continue
|
||||||
uniquename = self.dlfiles.add_file(docname, filename)
|
uniquename = self.dlfiles.add_file(docname, filename)
|
||||||
node['filename'] = uniquename
|
node['filename'] = uniquename
|
||||||
@ -919,8 +921,8 @@ class BuildEnvironment(object):
|
|||||||
if mimetype not in candidates:
|
if mimetype not in candidates:
|
||||||
globbed.setdefault(mimetype, []).append(new_imgpath)
|
globbed.setdefault(mimetype, []).append(new_imgpath)
|
||||||
except (OSError, IOError) as err:
|
except (OSError, IOError) as err:
|
||||||
self.warn_node('image file %s not readable: %s' %
|
logger.warn_node('image file %s not readable: %s' %
|
||||||
(filename, err), node)
|
(filename, err), node)
|
||||||
for key, files in iteritems(globbed):
|
for key, files in iteritems(globbed):
|
||||||
candidates[key] = sorted(files, key=len)[0] # select by similarity
|
candidates[key] = sorted(files, key=len)[0] # select by similarity
|
||||||
|
|
||||||
@ -932,13 +934,13 @@ class BuildEnvironment(object):
|
|||||||
node['candidates'] = candidates = {}
|
node['candidates'] = candidates = {}
|
||||||
imguri = node['uri']
|
imguri = node['uri']
|
||||||
if imguri.startswith('data:'):
|
if imguri.startswith('data:'):
|
||||||
self.warn_node('image data URI found. some builders might not support', node,
|
logger.warn_node('image data URI found. some builders might not support', node,
|
||||||
type='image', subtype='data_uri')
|
type='image', subtype='data_uri')
|
||||||
candidates['?'] = imguri
|
candidates['?'] = imguri
|
||||||
continue
|
continue
|
||||||
elif imguri.find('://') != -1:
|
elif imguri.find('://') != -1:
|
||||||
self.warn_node('nonlocal image URI found: %s' % imguri, node,
|
logger.warn_node('nonlocal image URI found: %s' % imguri, node,
|
||||||
type='image', subtype='nonlocal_uri')
|
type='image', subtype='nonlocal_uri')
|
||||||
candidates['?'] = imguri
|
candidates['?'] = imguri
|
||||||
continue
|
continue
|
||||||
rel_imgpath, full_imgpath = self.relfn2path(imguri, docname)
|
rel_imgpath, full_imgpath = self.relfn2path(imguri, docname)
|
||||||
@ -967,8 +969,8 @@ class BuildEnvironment(object):
|
|||||||
for imgpath in itervalues(candidates):
|
for imgpath in itervalues(candidates):
|
||||||
self.dependencies[docname].add(imgpath)
|
self.dependencies[docname].add(imgpath)
|
||||||
if not os.access(path.join(self.srcdir, imgpath), os.R_OK):
|
if not os.access(path.join(self.srcdir, imgpath), os.R_OK):
|
||||||
self.warn_node('image file not readable: %s' % imgpath,
|
logger.warn_node('image file not readable: %s' % imgpath,
|
||||||
node)
|
node)
|
||||||
continue
|
continue
|
||||||
self.images.add_file(docname, imgpath)
|
self.images.add_file(docname, imgpath)
|
||||||
|
|
||||||
@ -1152,7 +1154,7 @@ class BuildEnvironment(object):
|
|||||||
node.replace_self(newnode or contnode)
|
node.replace_self(newnode or contnode)
|
||||||
|
|
||||||
# remove only-nodes that do not belong to our builder
|
# remove only-nodes that do not belong to our builder
|
||||||
process_only_nodes(doctree, builder.tags, warn_node=self.warn_node)
|
process_only_nodes(doctree, builder.tags)
|
||||||
|
|
||||||
# allow custom references to be resolved
|
# allow custom references to be resolved
|
||||||
builder.app.emit('doctree-resolved', doctree, fromdocname)
|
builder.app.emit('doctree-resolved', doctree, fromdocname)
|
||||||
@ -1181,7 +1183,7 @@ class BuildEnvironment(object):
|
|||||||
(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
|
||||||
self.warn_node(msg % {'target': target}, node, type='ref', subtype=typ)
|
logger.warn_node(msg % {'target': target}, node, type='ref', subtype=typ)
|
||||||
|
|
||||||
def _resolve_doc_reference(self, builder, refdoc, node, contnode):
|
def _resolve_doc_reference(self, builder, refdoc, node, contnode):
|
||||||
# type: (Builder, unicode, nodes.Node, nodes.Node) -> nodes.Node
|
# type: (Builder, unicode, nodes.Node, nodes.Node) -> nodes.Node
|
||||||
@ -1232,9 +1234,9 @@ class BuildEnvironment(object):
|
|||||||
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)
|
||||||
self.warn_node('more than one target found for \'any\' cross-'
|
logger.warn_node('more than one target found for \'any\' cross-'
|
||||||
'reference %r: could be %s' % (target, nice_results),
|
'reference %r: could be %s' % (target, nice_results),
|
||||||
node)
|
node)
|
||||||
res_role, newnode = results[0]
|
res_role, newnode = results[0]
|
||||||
# Override "any" class with the actual role type to get the styling
|
# Override "any" class with the actual role type to get the styling
|
||||||
# approximately correct.
|
# approximately correct.
|
||||||
@ -1255,7 +1257,7 @@ class BuildEnvironment(object):
|
|||||||
|
|
||||||
def traverse_toctree(parent, docname):
|
def traverse_toctree(parent, docname):
|
||||||
if parent == docname:
|
if parent == docname:
|
||||||
self.warn(docname, 'self referenced toctree found. Ignored.')
|
logger.warning('self referenced toctree found. Ignored.', location=docname)
|
||||||
return
|
return
|
||||||
|
|
||||||
# traverse toctree by pre-order
|
# traverse toctree by pre-order
|
||||||
@ -1295,4 +1297,5 @@ class BuildEnvironment(object):
|
|||||||
continue
|
continue
|
||||||
if 'orphan' in self.metadata[docname]:
|
if 'orphan' in self.metadata[docname]:
|
||||||
continue
|
continue
|
||||||
self.warn(docname, 'document isn\'t included in any toctree')
|
logger.warning('document isn\'t included in any toctree',
|
||||||
|
location=docname)
|
||||||
|
@ -16,7 +16,7 @@ from itertools import groupby
|
|||||||
|
|
||||||
from six import text_type
|
from six import text_type
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.util import iteritems, split_index_msg, split_into
|
from sphinx.util import iteritems, split_index_msg, split_into, logging
|
||||||
from sphinx.locale import _
|
from sphinx.locale import _
|
||||||
from sphinx.environment.managers import EnvironmentManager
|
from sphinx.environment.managers import EnvironmentManager
|
||||||
|
|
||||||
@ -27,6 +27,8 @@ if False:
|
|||||||
from sphinx.builders import Builder # NOQA
|
from sphinx.builders import Builder # NOQA
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
from sphinx.environment import BuildEnvironment # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class IndexEntries(EnvironmentManager):
|
class IndexEntries(EnvironmentManager):
|
||||||
name = 'indices'
|
name = 'indices'
|
||||||
@ -53,7 +55,7 @@ class IndexEntries(EnvironmentManager):
|
|||||||
for entry in node['entries']:
|
for entry in node['entries']:
|
||||||
split_index_msg(entry[0], entry[1])
|
split_index_msg(entry[0], entry[1])
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
self.env.warn_node(exc, node)
|
logger.warn_node(str(exc), node)
|
||||||
node.parent.remove(node)
|
node.parent.remove(node)
|
||||||
else:
|
else:
|
||||||
for entry in node['entries']:
|
for entry in node['entries']:
|
||||||
@ -119,9 +121,9 @@ class IndexEntries(EnvironmentManager):
|
|||||||
add_entry(first, _('see also %s') % second, None,
|
add_entry(first, _('see also %s') % second, None,
|
||||||
link=False, key=index_key)
|
link=False, key=index_key)
|
||||||
else:
|
else:
|
||||||
self.env.warn(fn, 'unknown index entry type %r' % type)
|
logger.warning('unknown index entry type %r', type, location=fn)
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
self.env.warn(fn, str(err))
|
logger.warning(str(err), location=fn)
|
||||||
|
|
||||||
# sort the index entries; put all symbols at the front, even those
|
# sort the index entries; put all symbols at the front, even those
|
||||||
# following the letters in ASCII, this is where the chr(127) comes from
|
# following the letters in ASCII, this is where the chr(127) comes from
|
||||||
|
@ -14,7 +14,7 @@ from six import iteritems
|
|||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.util import url_re
|
from sphinx.util import url_re, logging
|
||||||
from sphinx.util.nodes import clean_astext, process_only_nodes
|
from sphinx.util.nodes import clean_astext, process_only_nodes
|
||||||
from sphinx.transforms import SphinxContentsFilter
|
from sphinx.transforms import SphinxContentsFilter
|
||||||
from sphinx.environment.managers import EnvironmentManager
|
from sphinx.environment.managers import EnvironmentManager
|
||||||
@ -25,6 +25,8 @@ if False:
|
|||||||
from sphinx.builders import Builder # NOQA
|
from sphinx.builders import Builder # NOQA
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
from sphinx.environment import BuildEnvironment # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Toctree(EnvironmentManager):
|
class Toctree(EnvironmentManager):
|
||||||
name = 'toctree'
|
name = 'toctree'
|
||||||
@ -169,7 +171,7 @@ class Toctree(EnvironmentManager):
|
|||||||
# the document does not exist anymore: return a dummy node that
|
# the document does not exist anymore: return a dummy node that
|
||||||
# renders to nothing
|
# renders to nothing
|
||||||
return nodes.paragraph()
|
return nodes.paragraph()
|
||||||
process_only_nodes(toc, builder.tags, warn_node=self.env.warn_node)
|
process_only_nodes(toc, builder.tags)
|
||||||
for node in toc.traverse(nodes.reference):
|
for node in toc.traverse(nodes.reference):
|
||||||
node['refuri'] = node['anchorname'] or '#'
|
node['refuri'] = node['anchorname'] or '#'
|
||||||
return toc
|
return toc
|
||||||
@ -296,16 +298,17 @@ class Toctree(EnvironmentManager):
|
|||||||
toc = nodes.bullet_list('', item)
|
toc = nodes.bullet_list('', item)
|
||||||
else:
|
else:
|
||||||
if ref in parents:
|
if ref in parents:
|
||||||
self.env.warn(ref, 'circular toctree references '
|
logger.warning('circular toctree references '
|
||||||
'detected, ignoring: %s <- %s' %
|
'detected, ignoring: %s <- %s',
|
||||||
(ref, ' <- '.join(parents)))
|
ref, ' <- '.join(parents),
|
||||||
|
location=ref)
|
||||||
continue
|
continue
|
||||||
refdoc = ref
|
refdoc = ref
|
||||||
toc = self.tocs[ref].deepcopy()
|
toc = self.tocs[ref].deepcopy()
|
||||||
maxdepth = self.env.metadata[ref].get('tocdepth', 0)
|
maxdepth = self.env.metadata[ref].get('tocdepth', 0)
|
||||||
if ref not in toctree_ancestors or (prune and maxdepth > 0):
|
if ref not in toctree_ancestors or (prune and maxdepth > 0):
|
||||||
self._toctree_prune(toc, 2, maxdepth, collapse)
|
self._toctree_prune(toc, 2, maxdepth, collapse)
|
||||||
process_only_nodes(toc, builder.tags, warn_node=self.env.warn_node)
|
process_only_nodes(toc, builder.tags)
|
||||||
if title and toc.children and len(toc.children) == 1:
|
if title and toc.children and len(toc.children) == 1:
|
||||||
child = toc.children[0]
|
child = toc.children[0]
|
||||||
for refnode in child.traverse(nodes.reference):
|
for refnode in child.traverse(nodes.reference):
|
||||||
@ -314,13 +317,13 @@ class Toctree(EnvironmentManager):
|
|||||||
refnode.children = [nodes.Text(title)]
|
refnode.children = [nodes.Text(title)]
|
||||||
if not toc.children:
|
if not toc.children:
|
||||||
# empty toc means: no titles will show up in the toctree
|
# empty toc means: no titles will show up in the toctree
|
||||||
self.env.warn_node(
|
logger.warn_node(
|
||||||
'toctree contains reference to document %r that '
|
'toctree contains reference to document %r that '
|
||||||
'doesn\'t have a title: no link will be generated'
|
'doesn\'t have a title: no link will be generated'
|
||||||
% ref, toctreenode)
|
% ref, toctreenode)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# this is raised if the included file does not exist
|
# this is raised if the included file does not exist
|
||||||
self.env.warn_node(
|
logger.warn_node(
|
||||||
'toctree contains reference to nonexisting document %r'
|
'toctree contains reference to nonexisting document %r'
|
||||||
% ref, toctreenode)
|
% ref, toctreenode)
|
||||||
else:
|
else:
|
||||||
|
@ -10,8 +10,11 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
from sphinx.util import logging
|
||||||
from sphinx.util.nodes import clean_astext
|
from sphinx.util.nodes import clean_astext
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def register_sections_as_label(app, document):
|
def register_sections_as_label(app, document):
|
||||||
labels = app.env.domaindata['std']['labels']
|
labels = app.env.domaindata['std']['labels']
|
||||||
@ -23,8 +26,8 @@ def register_sections_as_label(app, document):
|
|||||||
sectname = clean_astext(node[0])
|
sectname = clean_astext(node[0])
|
||||||
|
|
||||||
if name in labels:
|
if name in labels:
|
||||||
app.env.warn_node('duplicate label %s, ' % name + 'other instance '
|
logger.warn_node('duplicate label %s, ' % name + 'other instance '
|
||||||
'in ' + app.env.doc2path(labels[name][0]), node)
|
'in ' + app.env.doc2path(labels[name][0]), node)
|
||||||
|
|
||||||
anonlabels[name] = docname, labelid
|
anonlabels[name] = docname, labelid
|
||||||
labels[name] = docname, labelid, sectname
|
labels[name] = docname, labelid, sectname
|
||||||
|
@ -608,13 +608,13 @@ def process_generate_options(app):
|
|||||||
|
|
||||||
suffix = get_rst_suffix(app)
|
suffix = get_rst_suffix(app)
|
||||||
if suffix is None:
|
if suffix is None:
|
||||||
app.warn('autosummary generats .rst files internally. '
|
logging.warning('autosummary generats .rst files internally. '
|
||||||
'But your source_suffix does not contain .rst. Skipped.')
|
'But your source_suffix does not contain .rst. Skipped.')
|
||||||
return
|
return
|
||||||
|
|
||||||
generate_autosummary_docs(genfiles, builder=app.builder,
|
generate_autosummary_docs(genfiles, builder=app.builder,
|
||||||
warn=app.warn, info=app.info, suffix=suffix,
|
warn=logger.warning, info=logger.info,
|
||||||
base_path=app.srcdir)
|
suffix=suffix, base_path=app.srcdir)
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
|
@ -20,6 +20,7 @@ from six.moves import cPickle as pickle
|
|||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
|
from sphinx.util import logging
|
||||||
from sphinx.util.inspect import safe_getattr
|
from sphinx.util.inspect import safe_getattr
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
@ -27,6 +28,8 @@ if False:
|
|||||||
from typing import Any, Callable, IO, Pattern, Tuple # NOQA
|
from typing import Any, Callable, IO, Pattern, Tuple # NOQA
|
||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# utility
|
# utility
|
||||||
def write_header(f, text, char='-'):
|
def write_header(f, text, char='-'):
|
||||||
@ -35,14 +38,14 @@ def write_header(f, text, char='-'):
|
|||||||
f.write(char * len(text) + '\n')
|
f.write(char * len(text) + '\n')
|
||||||
|
|
||||||
|
|
||||||
def compile_regex_list(name, exps, warnfunc):
|
def compile_regex_list(name, exps):
|
||||||
# type: (unicode, unicode, Callable) -> List[Pattern]
|
# type: (unicode, unicode) -> List[Pattern]
|
||||||
lst = []
|
lst = []
|
||||||
for exp in exps:
|
for exp in exps:
|
||||||
try:
|
try:
|
||||||
lst.append(re.compile(exp))
|
lst.append(re.compile(exp))
|
||||||
except Exception:
|
except Exception:
|
||||||
warnfunc('invalid regex %r in %s' % (exp, name))
|
logger.warning('invalid regex %r in %s', exp, name)
|
||||||
return lst
|
return lst
|
||||||
|
|
||||||
|
|
||||||
@ -62,21 +65,18 @@ class CoverageBuilder(Builder):
|
|||||||
try:
|
try:
|
||||||
self.c_regexes.append((name, re.compile(exp)))
|
self.c_regexes.append((name, re.compile(exp)))
|
||||||
except Exception:
|
except Exception:
|
||||||
self.warn('invalid regex %r in coverage_c_regexes' % exp)
|
logger.warning('invalid regex %r in coverage_c_regexes', exp)
|
||||||
|
|
||||||
self.c_ignorexps = {} # type: Dict[unicode, List[Pattern]]
|
self.c_ignorexps = {} # type: Dict[unicode, List[Pattern]]
|
||||||
for (name, exps) in iteritems(self.config.coverage_ignore_c_items):
|
for (name, exps) in iteritems(self.config.coverage_ignore_c_items):
|
||||||
self.c_ignorexps[name] = compile_regex_list(
|
self.c_ignorexps[name] = compile_regex_list('coverage_ignore_c_items',
|
||||||
'coverage_ignore_c_items', exps, self.warn)
|
exps)
|
||||||
self.mod_ignorexps = compile_regex_list(
|
self.mod_ignorexps = compile_regex_list('coverage_ignore_modules',
|
||||||
'coverage_ignore_modules', self.config.coverage_ignore_modules,
|
self.config.coverage_ignore_modules)
|
||||||
self.warn)
|
self.cls_ignorexps = compile_regex_list('coverage_ignore_classes',
|
||||||
self.cls_ignorexps = compile_regex_list(
|
self.config.coverage_ignore_classes)
|
||||||
'coverage_ignore_classes', self.config.coverage_ignore_classes,
|
self.fun_ignorexps = compile_regex_list('coverage_ignore_functions',
|
||||||
self.warn)
|
self.config.coverage_ignore_functions)
|
||||||
self.fun_ignorexps = compile_regex_list(
|
|
||||||
'coverage_ignore_functions', self.config.coverage_ignore_functions,
|
|
||||||
self.warn)
|
|
||||||
|
|
||||||
def get_outdated_docs(self):
|
def get_outdated_docs(self):
|
||||||
# type: () -> unicode
|
# type: () -> unicode
|
||||||
@ -147,8 +147,7 @@ class CoverageBuilder(Builder):
|
|||||||
try:
|
try:
|
||||||
mod = __import__(mod_name, fromlist=['foo'])
|
mod = __import__(mod_name, fromlist=['foo'])
|
||||||
except ImportError as err:
|
except ImportError as err:
|
||||||
self.warn('module %s could not be imported: %s' %
|
logger.warning('module %s could not be imported: %s', mod_name, err)
|
||||||
(mod_name, err))
|
|
||||||
self.py_undoc[mod_name] = {'error': err}
|
self.py_undoc[mod_name] = {'error': err}
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ Results of doctest builder run on %s
|
|||||||
def _warn_out(self, text):
|
def _warn_out(self, text):
|
||||||
# type: (unicode) -> None
|
# type: (unicode) -> None
|
||||||
if self.app.quiet or self.app.warningiserror:
|
if self.app.quiet or self.app.warningiserror:
|
||||||
self.warn(text)
|
logger.warning(text)
|
||||||
else:
|
else:
|
||||||
logger.info(text, nonl=True)
|
logger.info(text, nonl=True)
|
||||||
if isinstance(text, binary_type):
|
if isinstance(text, binary_type):
|
||||||
@ -347,9 +347,9 @@ Doctest summary
|
|||||||
for node in doctree.traverse(condition):
|
for node in doctree.traverse(condition):
|
||||||
source = 'test' in node and node['test'] or node.astext()
|
source = 'test' in node and node['test'] or node.astext()
|
||||||
if not source:
|
if not source:
|
||||||
self.warn('no code/output in %s block at %s:%s' %
|
logger.warning('no code/output in %s block at %s:%s',
|
||||||
(node.get('testnodetype', 'doctest'),
|
node.get('testnodetype', 'doctest'),
|
||||||
self.env.doc2path(docname), node.line))
|
self.env.doc2path(docname), node.line)
|
||||||
code = TestCode(source, type=node.get('testnodetype', 'doctest'),
|
code = TestCode(source, type=node.get('testnodetype', 'doctest'),
|
||||||
lineno=node.line, options=node.get('options'))
|
lineno=node.line, options=node.get('options'))
|
||||||
node_groups = node.get('groups', ['default'])
|
node_groups = node.get('groups', ['default'])
|
||||||
@ -442,9 +442,8 @@ Doctest summary
|
|||||||
doctest_encode(code[0].code, self.env.config.source_encoding), {}, # type: ignore # NOQA
|
doctest_encode(code[0].code, self.env.config.source_encoding), {}, # type: ignore # NOQA
|
||||||
group.name, filename_str, code[0].lineno)
|
group.name, filename_str, code[0].lineno)
|
||||||
except Exception:
|
except Exception:
|
||||||
self.warn('ignoring invalid doctest code: %r' %
|
logger.warning('ignoring invalid doctest code: %r', code[0].code,
|
||||||
code[0].code,
|
location=(filename, code[0].lineno))
|
||||||
'%s:%s' % (filename, code[0].lineno))
|
|
||||||
continue
|
continue
|
||||||
if not test.examples:
|
if not test.examples:
|
||||||
continue
|
continue
|
||||||
|
@ -26,6 +26,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.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
|
||||||
|
|
||||||
@ -34,6 +35,8 @@ if False:
|
|||||||
from typing import Any, Tuple # NOQA
|
from typing import Any, Tuple # NOQA
|
||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
mapname_re = re.compile(r'<map id="(.*?)"')
|
mapname_re = re.compile(r'<map id="(.*?)"')
|
||||||
|
|
||||||
@ -204,8 +207,8 @@ 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
|
||||||
self.builder.warn('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 = {}
|
||||||
self.builder._graphviz_warned_dot[graphviz_dot] = True
|
self.builder._graphviz_warned_dot[graphviz_dot] = True
|
||||||
@ -236,7 +239,7 @@ def warn_for_deprecated_option(self, node):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if 'inline' in node:
|
if 'inline' in node:
|
||||||
self.builder.warn(':inline: option for graphviz is deprecated since version 1.4.0.')
|
logger.warning(':inline: option for graphviz is deprecated since version 1.4.0.')
|
||||||
self.builder._graphviz_warned_inline = True
|
self.builder._graphviz_warned_inline = True
|
||||||
|
|
||||||
|
|
||||||
@ -250,7 +253,7 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
|
|||||||
"'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:
|
||||||
self.builder.warn('dot code %r: ' % code + str(exc))
|
logger.warning('dot code %r: ' % code + str(exc))
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
if fname is None:
|
if fname is None:
|
||||||
@ -296,7 +299,7 @@ def render_dot_latex(self, node, code, options, prefix='graphviz'):
|
|||||||
try:
|
try:
|
||||||
fname, outfn = render_dot(self, code, options, 'pdf', prefix)
|
fname, outfn = render_dot(self, code, options, 'pdf', prefix)
|
||||||
except GraphvizError as exc:
|
except GraphvizError as exc:
|
||||||
self.builder.warn('dot code %r: ' % code + str(exc))
|
logger.warning('dot code %r: ' % code + str(exc))
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
is_inline = self.is_inline(node)
|
is_inline = self.is_inline(node)
|
||||||
@ -333,7 +336,7 @@ def render_dot_texinfo(self, node, code, options, prefix='graphviz'):
|
|||||||
try:
|
try:
|
||||||
fname, outfn = render_dot(self, code, options, 'png', prefix)
|
fname, outfn = render_dot(self, code, options, 'png', prefix)
|
||||||
except GraphvizError as exc:
|
except GraphvizError as exc:
|
||||||
self.builder.warn('dot code %r: ' % code + str(exc))
|
logger.warning('dot code %r: ' % code + str(exc))
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
if fname is not None:
|
if fname is not None:
|
||||||
self.body.append('@image{%s,,,[graphviz],png}\n' % fname[:-4])
|
self.body.append('@image{%s,,,[graphviz],png}\n' % fname[:-4])
|
||||||
|
@ -25,6 +25,7 @@ from docutils import nodes
|
|||||||
import sphinx
|
import sphinx
|
||||||
from sphinx.locale import _
|
from sphinx.locale import _
|
||||||
from sphinx.errors import SphinxError, ExtensionError
|
from sphinx.errors import SphinxError, ExtensionError
|
||||||
|
from sphinx.util import logging
|
||||||
from sphinx.util.png import read_png_depth, write_png_depth
|
from sphinx.util.png import read_png_depth, write_png_depth
|
||||||
from sphinx.util.osutil import ensuredir, ENOENT, cd
|
from sphinx.util.osutil import ensuredir, ENOENT, cd
|
||||||
from sphinx.util.pycompat import sys_encoding
|
from sphinx.util.pycompat import sys_encoding
|
||||||
@ -36,6 +37,8 @@ if False:
|
|||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
from sphinx.ext.mathbase import math as math_node, displaymath # NOQA
|
from sphinx.ext.mathbase import math as math_node, displaymath # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class MathExtError(SphinxError):
|
class MathExtError(SphinxError):
|
||||||
category = 'Math extension error'
|
category = 'Math extension error'
|
||||||
@ -142,9 +145,9 @@ def render_math(self, math):
|
|||||||
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
|
||||||
self.builder.warn('LaTeX command %r cannot be run (needed for math '
|
logger.warning('LaTeX command %r cannot be run (needed for math '
|
||||||
'display), check the imgmath_latex setting' %
|
'display), check the imgmath_latex setting',
|
||||||
self.builder.config.imgmath_latex)
|
self.builder.config.imgmath_latex)
|
||||||
self.builder._imgmath_warned_latex = True
|
self.builder._imgmath_warned_latex = True
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
@ -183,10 +186,10 @@ def render_math(self, math):
|
|||||||
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
|
||||||
self.builder.warn('%s command %r cannot be run (needed for math '
|
logger.warning('%s command %r cannot be run (needed for math '
|
||||||
'display), check the imgmath_%s setting' %
|
'display), check the imgmath_%s setting',
|
||||||
(image_translator, image_translator_executable,
|
image_translator, image_translator_executable,
|
||||||
image_translator))
|
image_translator)
|
||||||
self.builder._imgmath_warned_image_translator = True
|
self.builder._imgmath_warned_image_translator = True
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
@ -234,7 +237,7 @@ def html_visit_math(self, node):
|
|||||||
sm = nodes.system_message(msg, type='WARNING', level=2,
|
sm = nodes.system_message(msg, type='WARNING', level=2,
|
||||||
backrefs=[], source=node['latex'])
|
backrefs=[], source=node['latex'])
|
||||||
sm.walkabout(self)
|
sm.walkabout(self)
|
||||||
self.builder.warn('display latex %r: ' % node['latex'] + msg)
|
logger.warning('display latex %r: ' % node['latex'] + msg)
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
if fname is None:
|
if fname is None:
|
||||||
# something failed -- use text-only as a bad substitute
|
# something failed -- use text-only as a bad substitute
|
||||||
@ -262,7 +265,7 @@ def html_visit_displaymath(self, node):
|
|||||||
sm = nodes.system_message(msg, type='WARNING', level=2,
|
sm = nodes.system_message(msg, type='WARNING', level=2,
|
||||||
backrefs=[], source=node['latex'])
|
backrefs=[], source=node['latex'])
|
||||||
sm.walkabout(self)
|
sm.walkabout(self)
|
||||||
self.builder.warn('inline latex %r: ' % node['latex'] + msg)
|
logger.warning('inline latex %r: ' % node['latex'] + msg)
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
self.body.append(self.starttag(node, 'div', CLASS='math'))
|
self.body.append(self.starttag(node, 'div', CLASS='math'))
|
||||||
self.body.append('<p>')
|
self.body.append('<p>')
|
||||||
|
@ -229,14 +229,14 @@ def fetch_inventory(app, uri, inv):
|
|||||||
else:
|
else:
|
||||||
f = open(path.join(app.srcdir, inv), 'rb')
|
f = open(path.join(app.srcdir, inv), 'rb')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
app.warn('intersphinx inventory %r not fetchable due to '
|
logger.warning('intersphinx inventory %r not fetchable due to %s: %s',
|
||||||
'%s: %s' % (inv, err.__class__, err))
|
inv, err.__class__, err)
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
if hasattr(f, 'url'):
|
if hasattr(f, 'url'):
|
||||||
newinv = f.url # type: ignore
|
newinv = f.url # type: ignore
|
||||||
if inv != newinv:
|
if inv != newinv:
|
||||||
logger.info('intersphinx inventory has moved: %s -> %s' % (inv, newinv))
|
logger.info('intersphinx inventory has moved: %s -> %s', inv, newinv)
|
||||||
|
|
||||||
if uri in (inv, path.dirname(inv), path.dirname(inv) + '/'):
|
if uri in (inv, path.dirname(inv), path.dirname(inv) + '/'):
|
||||||
uri = path.dirname(newinv)
|
uri = path.dirname(newinv)
|
||||||
@ -247,8 +247,8 @@ def fetch_inventory(app, uri, inv):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValueError('unknown or unsupported inventory version')
|
raise ValueError('unknown or unsupported inventory version')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
app.warn('intersphinx inventory %r not readable due to '
|
logger.warning('intersphinx inventory %r not readable due to %s: %s',
|
||||||
'%s: %s' % (inv, err.__class__.__name__, err))
|
inv, err.__class__.__name__, err)
|
||||||
else:
|
else:
|
||||||
return invdata
|
return invdata
|
||||||
|
|
||||||
@ -274,7 +274,7 @@ def load_mappings(app):
|
|||||||
# new format
|
# new format
|
||||||
name, (uri, inv) = key, value
|
name, (uri, inv) = key, value
|
||||||
if not isinstance(name, string_types):
|
if not isinstance(name, string_types):
|
||||||
app.warn('intersphinx identifier %r is not string. Ignored' % name)
|
logger.warning('intersphinx identifier %r is not string. Ignored', name)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
# old format, no name
|
# old format, no name
|
||||||
@ -295,8 +295,7 @@ def load_mappings(app):
|
|||||||
if '://' not in inv or uri not in cache \
|
if '://' not in inv or uri not in cache \
|
||||||
or cache[uri][1] < cache_time:
|
or cache[uri][1] < cache_time:
|
||||||
safe_inv_url = _get_safe_url(inv) # type: ignore
|
safe_inv_url = _get_safe_url(inv) # type: ignore
|
||||||
logger.info(
|
logger.info('loading intersphinx inventory from %s...', safe_inv_url)
|
||||||
'loading intersphinx inventory from %s...' % safe_inv_url)
|
|
||||||
invdata = fetch_inventory(app, uri, inv)
|
invdata = fetch_inventory(app, uri, inv)
|
||||||
if invdata:
|
if invdata:
|
||||||
cache[uri] = (name, now, invdata)
|
cache[uri] = (name, now, invdata)
|
||||||
|
@ -25,6 +25,7 @@ from docutils import nodes
|
|||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
from sphinx.errors import SphinxError, ExtensionError
|
from sphinx.errors import SphinxError, ExtensionError
|
||||||
|
from sphinx.util import logging
|
||||||
from sphinx.util.png import read_png_depth, write_png_depth
|
from sphinx.util.png import read_png_depth, write_png_depth
|
||||||
from sphinx.util.osutil import ensuredir, ENOENT, cd
|
from sphinx.util.osutil import ensuredir, ENOENT, cd
|
||||||
from sphinx.util.pycompat import sys_encoding
|
from sphinx.util.pycompat import sys_encoding
|
||||||
@ -36,6 +37,8 @@ if False:
|
|||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
from sphinx.ext.mathbase import math as math_node, displaymath # NOQA
|
from sphinx.ext.mathbase import math as math_node, displaymath # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class MathExtError(SphinxError):
|
class MathExtError(SphinxError):
|
||||||
category = 'Math extension error'
|
category = 'Math extension error'
|
||||||
@ -133,9 +136,9 @@ def render_math(self, math):
|
|||||||
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
|
||||||
self.builder.warn('LaTeX command %r cannot be run (needed for math '
|
logger.warning('LaTeX command %r cannot be run (needed for math '
|
||||||
'display), check the pngmath_latex setting' %
|
'display), check the pngmath_latex setting',
|
||||||
self.builder.config.pngmath_latex)
|
self.builder.config.pngmath_latex)
|
||||||
self.builder._mathpng_warned_latex = True
|
self.builder._mathpng_warned_latex = True
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
@ -158,9 +161,9 @@ def render_math(self, math):
|
|||||||
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
|
||||||
self.builder.warn('dvipng command %r cannot be run (needed for math '
|
logger.warning('dvipng command %r cannot be run (needed for math '
|
||||||
'display), check the pngmath_dvipng setting' %
|
'display), check the pngmath_dvipng setting',
|
||||||
self.builder.config.pngmath_dvipng)
|
self.builder.config.pngmath_dvipng)
|
||||||
self.builder._mathpng_warned_dvipng = True
|
self.builder._mathpng_warned_dvipng = True
|
||||||
return None, None
|
return None, None
|
||||||
stdout, stderr = p.communicate()
|
stdout, stderr = p.communicate()
|
||||||
@ -206,7 +209,7 @@ def html_visit_math(self, node):
|
|||||||
sm = nodes.system_message(msg, type='WARNING', level=2,
|
sm = nodes.system_message(msg, type='WARNING', level=2,
|
||||||
backrefs=[], source=node['latex'])
|
backrefs=[], source=node['latex'])
|
||||||
sm.walkabout(self)
|
sm.walkabout(self)
|
||||||
self.builder.warn('display latex %r: ' % node['latex'] + msg)
|
logger.warning('display latex %r: ' % node['latex'] + msg)
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
if fname is None:
|
if fname is None:
|
||||||
# something failed -- use text-only as a bad substitute
|
# something failed -- use text-only as a bad substitute
|
||||||
@ -234,7 +237,7 @@ def html_visit_displaymath(self, node):
|
|||||||
sm = nodes.system_message(msg, type='WARNING', level=2,
|
sm = nodes.system_message(msg, type='WARNING', level=2,
|
||||||
backrefs=[], source=node['latex'])
|
backrefs=[], source=node['latex'])
|
||||||
sm.walkabout(self)
|
sm.walkabout(self)
|
||||||
self.builder.warn('inline latex %r: ' % node['latex'] + msg)
|
logger.warning('inline latex %r: ' % node['latex'] + msg)
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
self.body.append(self.starttag(node, 'div', CLASS='math'))
|
self.body.append(self.starttag(node, 'div', CLASS='math'))
|
||||||
self.body.append('<p>')
|
self.body.append('<p>')
|
||||||
@ -252,7 +255,8 @@ def html_visit_displaymath(self, node):
|
|||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
# type: (Sphinx) -> Dict[unicode, Any]
|
# type: (Sphinx) -> Dict[unicode, Any]
|
||||||
app.warn('sphinx.ext.pngmath has been deprecated. Please use sphinx.ext.imgmath instead.')
|
logger.warning('sphinx.ext.pngmath has been deprecated. '
|
||||||
|
'Please use sphinx.ext.imgmath instead.')
|
||||||
try:
|
try:
|
||||||
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
|
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
|
||||||
except ExtensionError:
|
except ExtensionError:
|
||||||
|
@ -18,6 +18,7 @@ from docutils.parsers.rst import directives
|
|||||||
import sphinx
|
import sphinx
|
||||||
from sphinx.locale import _
|
from sphinx.locale import _
|
||||||
from sphinx.environment import NoUri
|
from sphinx.environment import NoUri
|
||||||
|
from sphinx.util import logging
|
||||||
from sphinx.util.nodes import set_source_info
|
from sphinx.util.nodes import set_source_info
|
||||||
from docutils.parsers.rst import Directive
|
from docutils.parsers.rst import Directive
|
||||||
from docutils.parsers.rst.directives.admonitions import BaseAdmonition
|
from docutils.parsers.rst.directives.admonitions import BaseAdmonition
|
||||||
@ -28,6 +29,8 @@ if False:
|
|||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
from sphinx.environment import BuildEnvironment # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class todo_node(nodes.Admonition, nodes.Element):
|
class todo_node(nodes.Admonition, nodes.Element):
|
||||||
pass
|
pass
|
||||||
@ -97,7 +100,7 @@ def process_todos(app, doctree):
|
|||||||
})
|
})
|
||||||
|
|
||||||
if env.config.todo_emit_warnings:
|
if env.config.todo_emit_warnings:
|
||||||
env.warn_node("TODO entry found: %s" % node[1].astext(), node)
|
logger.warn_node("TODO entry found: %s" % node[1].astext(), node)
|
||||||
|
|
||||||
|
|
||||||
class TodoList(Directive):
|
class TodoList(Directive):
|
||||||
|
@ -39,7 +39,7 @@ def _get_full_modname(app, modname, attribute):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
# sphinx.ext.viewcode can't follow class instance attribute
|
# sphinx.ext.viewcode can't follow class instance attribute
|
||||||
# then AttributeError logging output only verbose mode.
|
# then AttributeError logging output only verbose mode.
|
||||||
logger.verbose('Didn\'t find %s in %s' % (attribute, modname))
|
logger.verbose('Didn\'t find %s in %s', attribute, modname)
|
||||||
return None
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# sphinx.ext.viewcode follow python domain directives.
|
# sphinx.ext.viewcode follow python domain directives.
|
||||||
|
@ -177,12 +177,11 @@ class AutoIndexUpgrader(Transform):
|
|||||||
|
|
||||||
def apply(self):
|
def apply(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
env = self.document.settings.env
|
|
||||||
for node in self.document.traverse(addnodes.index):
|
for node in self.document.traverse(addnodes.index):
|
||||||
if 'entries' in node and any(len(entry) == 4 for entry in node['entries']):
|
if 'entries' in node and any(len(entry) == 4 for entry in node['entries']):
|
||||||
msg = ('4 column based index found. '
|
msg = ('4 column based index found. '
|
||||||
'It might be a bug of extensions you use: %r' % node['entries'])
|
'It might be a bug of extensions you use: %r' % node['entries'])
|
||||||
env.warn_node(msg, node)
|
logger.warn_node(msg, node)
|
||||||
for i, entry in enumerate(node['entries']):
|
for i, entry in enumerate(node['entries']):
|
||||||
if len(entry) == 4:
|
if len(entry) == 4:
|
||||||
node['entries'][i] = entry + (None,)
|
node['entries'][i] = entry + (None,)
|
||||||
|
@ -17,7 +17,7 @@ from docutils.utils import relative_path
|
|||||||
from docutils.transforms import Transform
|
from docutils.transforms import Transform
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.util import split_index_msg
|
from sphinx.util import split_index_msg, logging
|
||||||
from sphinx.util.i18n import find_catalog
|
from sphinx.util.i18n import find_catalog
|
||||||
from sphinx.util.nodes import (
|
from sphinx.util.nodes import (
|
||||||
LITERAL_TYPE_NODES, IMAGE_TYPE_NODES,
|
LITERAL_TYPE_NODES, IMAGE_TYPE_NODES,
|
||||||
@ -33,6 +33,8 @@ if False:
|
|||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
from sphinx.config import Config # NOQA
|
from sphinx.config import Config # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def publish_msgstr(app, source, source_path, source_line, config, settings):
|
def publish_msgstr(app, source, source_path, source_line, config, settings):
|
||||||
# type: (Sphinx, unicode, unicode, int, Config, Dict) -> nodes.document
|
# type: (Sphinx, unicode, unicode, int, Config, Dict) -> nodes.document
|
||||||
@ -272,8 +274,8 @@ class Locale(Transform):
|
|||||||
old_foot_refs = node.traverse(is_autonumber_footnote_ref)
|
old_foot_refs = node.traverse(is_autonumber_footnote_ref)
|
||||||
new_foot_refs = patch.traverse(is_autonumber_footnote_ref)
|
new_foot_refs = patch.traverse(is_autonumber_footnote_ref)
|
||||||
if len(old_foot_refs) != len(new_foot_refs):
|
if len(old_foot_refs) != len(new_foot_refs):
|
||||||
env.warn_node('inconsistent footnote references in '
|
logger.warn_node('inconsistent footnote references in '
|
||||||
'translated message', node)
|
'translated message', node)
|
||||||
old_foot_namerefs = {} # type: Dict[unicode, List[nodes.footnote_reference]]
|
old_foot_namerefs = {} # type: Dict[unicode, List[nodes.footnote_reference]]
|
||||||
for r in old_foot_refs:
|
for r in old_foot_refs:
|
||||||
old_foot_namerefs.setdefault(r.get('refname'), []).append(r)
|
old_foot_namerefs.setdefault(r.get('refname'), []).append(r)
|
||||||
@ -307,8 +309,7 @@ class Locale(Transform):
|
|||||||
old_refs = node.traverse(is_refnamed_ref)
|
old_refs = node.traverse(is_refnamed_ref)
|
||||||
new_refs = patch.traverse(is_refnamed_ref)
|
new_refs = patch.traverse(is_refnamed_ref)
|
||||||
if len(old_refs) != len(new_refs):
|
if len(old_refs) != len(new_refs):
|
||||||
env.warn_node('inconsistent references in '
|
logger.warn_node('inconsistent references in translated message', node)
|
||||||
'translated message', node)
|
|
||||||
old_ref_names = [r['refname'] for r in old_refs]
|
old_ref_names = [r['refname'] for r in old_refs]
|
||||||
new_ref_names = [r['refname'] for r in new_refs]
|
new_ref_names = [r['refname'] for r in new_refs]
|
||||||
orphans = list(set(old_ref_names) - set(new_ref_names))
|
orphans = list(set(old_ref_names) - set(new_ref_names))
|
||||||
@ -336,8 +337,7 @@ class Locale(Transform):
|
|||||||
new_refs = patch.traverse(is_refnamed_footnote_ref)
|
new_refs = patch.traverse(is_refnamed_footnote_ref)
|
||||||
refname_ids_map = {}
|
refname_ids_map = {}
|
||||||
if len(old_refs) != len(new_refs):
|
if len(old_refs) != len(new_refs):
|
||||||
env.warn_node('inconsistent references in '
|
logger.warn_node('inconsistent references in translated message', node)
|
||||||
'translated message', node)
|
|
||||||
for old in old_refs:
|
for old in old_refs:
|
||||||
refname_ids_map[old["refname"]] = old["ids"]
|
refname_ids_map[old["refname"]] = old["ids"]
|
||||||
for new in new_refs:
|
for new in new_refs:
|
||||||
@ -352,8 +352,7 @@ class Locale(Transform):
|
|||||||
new_refs = patch.traverse(addnodes.pending_xref)
|
new_refs = patch.traverse(addnodes.pending_xref)
|
||||||
xref_reftarget_map = {}
|
xref_reftarget_map = {}
|
||||||
if len(old_refs) != len(new_refs):
|
if len(old_refs) != len(new_refs):
|
||||||
env.warn_node('inconsistent term references in '
|
logger.warn_node('inconsistent term references in translated message', node)
|
||||||
'translated message', node)
|
|
||||||
|
|
||||||
def get_ref_key(node):
|
def get_ref_key(node):
|
||||||
# type: (nodes.Node) -> Tuple[unicode, unicode, unicode]
|
# type: (nodes.Node) -> Tuple[unicode, unicode, unicode]
|
||||||
|
@ -23,7 +23,7 @@ from sphinx.util.console import colorize
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Generator, IO, Tuple # NOQA
|
from typing import Any, Generator, IO, Tuple, Union # NOQA
|
||||||
from docutils import nodes # NOQA
|
from docutils import nodes # NOQA
|
||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.application import Sphinx # NOQA
|
||||||
|
|
||||||
@ -422,12 +422,12 @@ def setup(app, status, warning):
|
|||||||
for handler in logger.handlers[:]:
|
for handler in logger.handlers[:]:
|
||||||
logger.removeHandler(handler)
|
logger.removeHandler(handler)
|
||||||
|
|
||||||
info_handler = NewLineStreamHandler(SafeEncodingWriter(status))
|
info_handler = NewLineStreamHandler(SafeEncodingWriter(status)) # type: ignore
|
||||||
info_handler.addFilter(InfoFilter())
|
info_handler.addFilter(InfoFilter())
|
||||||
info_handler.setLevel(VERBOSITY_MAP.get(app.verbosity))
|
info_handler.setLevel(VERBOSITY_MAP.get(app.verbosity))
|
||||||
info_handler.setFormatter(ColorizeFormatter())
|
info_handler.setFormatter(ColorizeFormatter())
|
||||||
|
|
||||||
warning_handler = WarningStreamHandler(SafeEncodingWriter(warning))
|
warning_handler = WarningStreamHandler(SafeEncodingWriter(warning)) # type: ignore
|
||||||
warning_handler.addFilter(WarningSuppressor(app))
|
warning_handler.addFilter(WarningSuppressor(app))
|
||||||
warning_handler.addFilter(WarningIsErrorFilter(app))
|
warning_handler.addFilter(WarningIsErrorFilter(app))
|
||||||
warning_handler.addFilter(WarningLogRecordTranslator(app))
|
warning_handler.addFilter(WarningLogRecordTranslator(app))
|
||||||
|
@ -18,6 +18,7 @@ from docutils import nodes
|
|||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.locale import pairindextypes
|
from sphinx.locale import pairindextypes
|
||||||
|
from sphinx.util import logging
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
@ -25,6 +26,8 @@ if False:
|
|||||||
from sphinx.builders import Builder # NOQA
|
from sphinx.builders import Builder # NOQA
|
||||||
from sphinx.utils.tags import Tags # NOQA
|
from sphinx.utils.tags import Tags # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class WarningStream(object):
|
class WarningStream(object):
|
||||||
|
|
||||||
@ -304,15 +307,14 @@ def inline_all_toctrees(builder, docnameset, docname, tree, colorfunc, traversed
|
|||||||
if includefile not in traversed:
|
if includefile not in traversed:
|
||||||
try:
|
try:
|
||||||
traversed.append(includefile)
|
traversed.append(includefile)
|
||||||
builder.info(colorfunc(includefile) + " ", nonl=1)
|
logger.info(colorfunc(includefile) + " ", nonl=1)
|
||||||
subtree = inline_all_toctrees(builder, docnameset, includefile,
|
subtree = inline_all_toctrees(builder, docnameset, includefile,
|
||||||
builder.env.get_doctree(includefile),
|
builder.env.get_doctree(includefile),
|
||||||
colorfunc, traversed)
|
colorfunc, traversed)
|
||||||
docnameset.add(includefile)
|
docnameset.add(includefile)
|
||||||
except Exception:
|
except Exception:
|
||||||
builder.warn('toctree contains ref to nonexisting '
|
logger.warning('toctree contains ref to nonexisting file %r',
|
||||||
'file %r' % includefile,
|
includefile, location=docname)
|
||||||
builder.env.doc2path(docname))
|
|
||||||
else:
|
else:
|
||||||
sof = addnodes.start_of_file(docname=includefile)
|
sof = addnodes.start_of_file(docname=includefile)
|
||||||
sof.children = subtree.children
|
sof.children = subtree.children
|
||||||
@ -350,8 +352,8 @@ def set_role_source_info(inliner, lineno, node):
|
|||||||
node.source, node.line = inliner.reporter.get_source_and_line(lineno)
|
node.source, node.line = inliner.reporter.get_source_and_line(lineno)
|
||||||
|
|
||||||
|
|
||||||
def process_only_nodes(doctree, tags, warn_node=None):
|
def process_only_nodes(doctree, tags):
|
||||||
# type: (nodes.Node, Tags, Callable) -> None
|
# type: (nodes.Node, Tags) -> None
|
||||||
# A comment on the comment() nodes being inserted: replacing by [] would
|
# A comment on the comment() nodes being inserted: replacing by [] would
|
||||||
# result in a "Losing ids" exception if there is a target node before
|
# result in a "Losing ids" exception if there is a target node before
|
||||||
# the only node, so we make sure docutils can transfer the id to
|
# the only node, so we make sure docutils can transfer the id to
|
||||||
@ -360,10 +362,8 @@ def process_only_nodes(doctree, tags, warn_node=None):
|
|||||||
try:
|
try:
|
||||||
ret = tags.eval_condition(node['expr'])
|
ret = tags.eval_condition(node['expr'])
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
if warn_node is None:
|
logger.warn_node('exception while evaluating only '
|
||||||
raise err
|
'directive expression: %s' % err, node)
|
||||||
warn_node('exception while evaluating only '
|
|
||||||
'directive expression: %s' % err, node)
|
|
||||||
node.replace_self(node.children or nodes.comment())
|
node.replace_self(node.children or nodes.comment())
|
||||||
else:
|
else:
|
||||||
if ret:
|
if ret:
|
||||||
|
@ -22,9 +22,12 @@ from docutils.writers.html4css1 import Writer, HTMLTranslator as BaseTranslator
|
|||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.deprecation import RemovedInSphinx16Warning
|
from sphinx.deprecation import RemovedInSphinx16Warning
|
||||||
from sphinx.locale import admonitionlabels, _
|
from sphinx.locale import admonitionlabels, _
|
||||||
|
from sphinx.util import logging
|
||||||
from sphinx.util.images import get_image_size
|
from sphinx.util.images import get_image_size
|
||||||
from sphinx.util.smartypants import sphinx_smarty_pants
|
from sphinx.util.smartypants import sphinx_smarty_pants
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# A good overview of the purpose behind these classes can be found here:
|
# A good overview of the purpose behind these classes can be found here:
|
||||||
# http://www.arnebrodowski.de/blog/write-your-own-restructuredtext-writer.html
|
# http://www.arnebrodowski.de/blog/write-your-own-restructuredtext-writer.html
|
||||||
|
|
||||||
@ -289,7 +292,7 @@ class HTMLTranslator(BaseTranslator):
|
|||||||
prefix = self.builder.config.numfig_format.get(figtype)
|
prefix = self.builder.config.numfig_format.get(figtype)
|
||||||
if prefix is None:
|
if prefix is None:
|
||||||
msg = 'numfig_format is not defined for %s' % figtype
|
msg = 'numfig_format is not defined for %s' % figtype
|
||||||
self.builder.warn(msg)
|
logger.warning(msg)
|
||||||
else:
|
else:
|
||||||
numbers = self.builder.fignumbers[key][figure_id]
|
numbers = self.builder.fignumbers[key][figure_id]
|
||||||
self.body.append(prefix % '.'.join(map(str, numbers)) + ' ')
|
self.body.append(prefix % '.'.join(map(str, numbers)) + ' ')
|
||||||
@ -299,7 +302,7 @@ class HTMLTranslator(BaseTranslator):
|
|||||||
if figtype:
|
if figtype:
|
||||||
if len(node['ids']) == 0:
|
if len(node['ids']) == 0:
|
||||||
msg = 'Any IDs not assigned for %s node' % node.tagname
|
msg = 'Any IDs not assigned for %s node' % node.tagname
|
||||||
self.builder.env.warn_node(msg, node)
|
logger.warn_node(msg, node)
|
||||||
else:
|
else:
|
||||||
append_fignumber(figtype, node['ids'][0])
|
append_fignumber(figtype, node['ids'][0])
|
||||||
|
|
||||||
@ -522,8 +525,8 @@ class HTMLTranslator(BaseTranslator):
|
|||||||
if not ('width' in node and 'height' in node):
|
if not ('width' in node and 'height' in node):
|
||||||
size = get_image_size(os.path.join(self.builder.srcdir, olduri))
|
size = get_image_size(os.path.join(self.builder.srcdir, olduri))
|
||||||
if size is None:
|
if size is None:
|
||||||
self.builder.env.warn_node('Could not obtain image size. '
|
logger.warn_node('Could not obtain image size. '
|
||||||
':scale: option is ignored.', node)
|
':scale: option is ignored.', node)
|
||||||
else:
|
else:
|
||||||
if 'width' not in node:
|
if 'width' not in node:
|
||||||
node['width'] = str(size[0])
|
node['width'] = str(size[0])
|
||||||
@ -755,10 +758,10 @@ class HTMLTranslator(BaseTranslator):
|
|||||||
self.body.append(self.starttag(node, 'tr', '', CLASS='field'))
|
self.body.append(self.starttag(node, 'tr', '', CLASS='field'))
|
||||||
|
|
||||||
def visit_math(self, node, math_env=''):
|
def visit_math(self, node, math_env=''):
|
||||||
self.builder.warn('using "math" markup without a Sphinx math extension '
|
logger.warning('using "math" markup without a Sphinx math extension '
|
||||||
'active, please use one of the math extensions '
|
'active, please use one of the math extensions '
|
||||||
'described at http://sphinx-doc.org/ext/math.html',
|
'described at http://sphinx-doc.org/ext/math.html',
|
||||||
(self.builder.current_docname, node.line))
|
location=(self.builder.current_docname, node.line))
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
def unknown_visit(self, node):
|
def unknown_visit(self, node):
|
||||||
|
@ -26,7 +26,7 @@ from sphinx import highlighting
|
|||||||
from sphinx.errors import SphinxError
|
from sphinx.errors import SphinxError
|
||||||
from sphinx.deprecation import RemovedInSphinx16Warning
|
from sphinx.deprecation import RemovedInSphinx16Warning
|
||||||
from sphinx.locale import admonitionlabels, _
|
from sphinx.locale import admonitionlabels, _
|
||||||
from sphinx.util import split_into
|
from sphinx.util import split_into, logging
|
||||||
from sphinx.util.i18n import format_date
|
from sphinx.util.i18n import format_date
|
||||||
from sphinx.util.nodes import clean_astext, traverse_parent
|
from sphinx.util.nodes import clean_astext, traverse_parent
|
||||||
from sphinx.util.template import LaTeXRenderer
|
from sphinx.util.template import LaTeXRenderer
|
||||||
@ -38,6 +38,7 @@ if False:
|
|||||||
from typing import Any, Callable, Iterator, Pattern, Tuple, Union # NOQA
|
from typing import Any, Callable, Iterator, Pattern, Tuple, Union # NOQA
|
||||||
from sphinx.builder import Builder # NOQA
|
from sphinx.builder import Builder # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
BEGIN_DOC = r'''
|
BEGIN_DOC = r'''
|
||||||
\begin{document}
|
\begin{document}
|
||||||
@ -438,8 +439,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
if builder.config.language and not self.babel.is_supported_language():
|
if builder.config.language and not self.babel.is_supported_language():
|
||||||
# emit warning if specified language is invalid
|
# emit warning if specified language is invalid
|
||||||
# (only emitting, nothing changed to processing)
|
# (only emitting, nothing changed to processing)
|
||||||
self.builder.warn('no Babel option known for language %r' %
|
logger.warning('no Babel option known for language %r',
|
||||||
builder.config.language)
|
builder.config.language)
|
||||||
|
|
||||||
# simply use babel.get_language() always, as get_language() returns
|
# simply use babel.get_language() always, as get_language() returns
|
||||||
# 'english' even if language is invalid or empty
|
# 'english' even if language is invalid or empty
|
||||||
@ -490,7 +491,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
tocdepth = document['tocdepth'] + self.top_sectionlevel - 2
|
tocdepth = document['tocdepth'] + self.top_sectionlevel - 2
|
||||||
maxdepth = len(self.sectionnames) - self.top_sectionlevel
|
maxdepth = len(self.sectionnames) - self.top_sectionlevel
|
||||||
if tocdepth > maxdepth:
|
if tocdepth > maxdepth:
|
||||||
self.builder.warn('too large :maxdepth:, ignored.')
|
logger.warning('too large :maxdepth:, ignored.')
|
||||||
tocdepth = maxdepth
|
tocdepth = maxdepth
|
||||||
|
|
||||||
self.elements['tocdepth'] = '\\setcounter{tocdepth}{%d}' % tocdepth
|
self.elements['tocdepth'] = '\\setcounter{tocdepth}{%d}' % tocdepth
|
||||||
@ -566,7 +567,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
for key in self.builder.config.latex_elements:
|
for key in self.builder.config.latex_elements:
|
||||||
if key not in self.elements:
|
if key not in self.elements:
|
||||||
msg = _("Unknown configure key: latex_elements[%r] is ignored.")
|
msg = _("Unknown configure key: latex_elements[%r] is ignored.")
|
||||||
self.builder.warn(msg % key)
|
logger.warning(msg % key)
|
||||||
|
|
||||||
def restrict_footnote(self, node):
|
def restrict_footnote(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
@ -891,8 +892,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
if self.this_is_the_title:
|
if self.this_is_the_title:
|
||||||
if len(node.children) != 1 and not isinstance(node.children[0],
|
if len(node.children) != 1 and not isinstance(node.children[0],
|
||||||
nodes.Text):
|
nodes.Text):
|
||||||
self.builder.warn('document title is not a single Text node',
|
logger.warning('document title is not a single Text node',
|
||||||
(self.curfilestack[-1], node.line))
|
location=(self.curfilestack[-1], node.line))
|
||||||
if not self.elements['title']:
|
if not self.elements['title']:
|
||||||
# text needs to be escaped since it is inserted into
|
# text needs to be escaped since it is inserted into
|
||||||
# the output literally
|
# the output literally
|
||||||
@ -930,10 +931,9 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
# Redirect body output until title is finished.
|
# Redirect body output until title is finished.
|
||||||
self.pushbody([])
|
self.pushbody([])
|
||||||
else:
|
else:
|
||||||
self.builder.warn(
|
logger.warning('encountered title node not in section, topic, table, '
|
||||||
'encountered title node not in section, topic, table, '
|
'admonition or sidebar',
|
||||||
'admonition or sidebar',
|
location=(self.curfilestack[-1], node.line or ''))
|
||||||
(self.curfilestack[-1], node.line or ''))
|
|
||||||
self.body.append('\\sphinxstyleothertitle{')
|
self.body.append('\\sphinxstyleothertitle{')
|
||||||
self.context.append('}\n')
|
self.context.append('}\n')
|
||||||
self.in_title = 1
|
self.in_title = 1
|
||||||
@ -1573,7 +1573,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
try:
|
try:
|
||||||
return rstdim_to_latexdim(width_str)
|
return rstdim_to_latexdim(width_str)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.builder.warn('dimension unit %s is invalid. Ignored.' % width_str)
|
logger.warning('dimension unit %s is invalid. Ignored.', width_str)
|
||||||
|
|
||||||
def is_inline(self, node):
|
def is_inline(self, node):
|
||||||
# type: (nodes.Node) -> bool
|
# type: (nodes.Node) -> bool
|
||||||
@ -1886,10 +1886,9 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
p1, p2 = [self.encode(x) for x in split_into(2, 'seealso', string)]
|
p1, p2 = [self.encode(x) for x in split_into(2, 'seealso', string)]
|
||||||
self.body.append(r'\index{%s|see{%s}}' % (p1, p2))
|
self.body.append(r'\index{%s|see{%s}}' % (p1, p2))
|
||||||
else:
|
else:
|
||||||
self.builder.warn(
|
logger.warning('unknown index entry type %s found', type)
|
||||||
'unknown index entry type %s found' % type)
|
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
self.builder.warn(str(err))
|
logger.warning(str(err))
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
def visit_raw(self, node):
|
def visit_raw(self, node):
|
||||||
@ -1953,8 +1952,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
else:
|
else:
|
||||||
self.context.append('}}}')
|
self.context.append('}}}')
|
||||||
else:
|
else:
|
||||||
self.builder.warn('unusable reference target found: %s' % uri,
|
logger.warning('unusable reference target found: %s', uri,
|
||||||
(self.curfilestack[-1], node.line))
|
location=(self.curfilestack[-1], node.line))
|
||||||
self.context.append('')
|
self.context.append('')
|
||||||
|
|
||||||
def depart_reference(self, node):
|
def depart_reference(self, node):
|
||||||
@ -2459,10 +2458,10 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
|
|
||||||
def visit_math(self, node):
|
def visit_math(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
self.builder.warn('using "math" markup without a Sphinx math extension '
|
logger.warning('using "math" markup without a Sphinx math extension '
|
||||||
'active, please use one of the math extensions '
|
'active, please use one of the math extensions '
|
||||||
'described at http://sphinx-doc.org/ext/math.html',
|
'described at http://sphinx-doc.org/ext/math.html',
|
||||||
(self.curfilestack[-1], node.line))
|
location=(self.curfilestack[-1], node.line))
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
visit_math_block = visit_math
|
visit_math_block = visit_math
|
||||||
|
@ -21,9 +21,12 @@ from docutils.writers.manpage import (
|
|||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.deprecation import RemovedInSphinx16Warning
|
from sphinx.deprecation import RemovedInSphinx16Warning
|
||||||
from sphinx.locale import admonitionlabels, _
|
from sphinx.locale import admonitionlabels, _
|
||||||
|
from sphinx.util import logging
|
||||||
import sphinx.util.docutils
|
import sphinx.util.docutils
|
||||||
from sphinx.util.i18n import format_date
|
from sphinx.util.i18n import format_date
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ManualPageWriter(Writer):
|
class ManualPageWriter(Writer):
|
||||||
def __init__(self, builder):
|
def __init__(self, builder):
|
||||||
@ -437,9 +440,9 @@ class ManualPageTranslator(BaseTranslator):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def visit_math(self, node):
|
def visit_math(self, node):
|
||||||
self.builder.warn('using "math" markup without a Sphinx math extension '
|
logger.warning('using "math" markup without a Sphinx math extension '
|
||||||
'active, please use one of the math extensions '
|
'active, please use one of the math extensions '
|
||||||
'described at http://sphinx-doc.org/ext/math.html')
|
'described at http://sphinx-doc.org/ext/math.html')
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
visit_math_block = visit_math
|
visit_math_block = visit_math
|
||||||
|
@ -23,6 +23,7 @@ from sphinx import addnodes, __display_version__
|
|||||||
from sphinx.errors import ExtensionError
|
from sphinx.errors import ExtensionError
|
||||||
from sphinx.deprecation import RemovedInSphinx16Warning
|
from sphinx.deprecation import RemovedInSphinx16Warning
|
||||||
from sphinx.locale import admonitionlabels, _
|
from sphinx.locale import admonitionlabels, _
|
||||||
|
from sphinx.util import logging
|
||||||
from sphinx.util.i18n import format_date
|
from sphinx.util.i18n import format_date
|
||||||
from sphinx.writers.latex import collected_footnote
|
from sphinx.writers.latex import collected_footnote
|
||||||
|
|
||||||
@ -31,6 +32,8 @@ if False:
|
|||||||
from typing import Any, Callable, Iterator, Pattern, Tuple, Union # NOQA
|
from typing import Any, Callable, Iterator, Pattern, Tuple, Union # NOQA
|
||||||
from sphinx.builders.texinfo import TexinfoBuilder # NOQA
|
from sphinx.builders.texinfo import TexinfoBuilder # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
COPYING = """\
|
COPYING = """\
|
||||||
@quotation
|
@quotation
|
||||||
@ -651,9 +654,9 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
|||||||
if isinstance(parent, (nodes.Admonition, nodes.sidebar, nodes.topic)):
|
if isinstance(parent, (nodes.Admonition, nodes.sidebar, nodes.topic)):
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
elif not isinstance(parent, nodes.section):
|
elif not isinstance(parent, nodes.section):
|
||||||
self.builder.warn(
|
logger.warning('encountered title node not in section, topic, table, '
|
||||||
'encountered title node not in section, topic, table, '
|
'admonition or sidebar',
|
||||||
'admonition or sidebar', (self.curfilestack[-1], node.line))
|
location=(self.curfilestack[-1], node.line))
|
||||||
self.visit_rubric(node)
|
self.visit_rubric(node)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@ -1331,8 +1334,8 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
|||||||
node.parent.get('literal_block'))):
|
node.parent.get('literal_block'))):
|
||||||
self.body.append('\n@caption{')
|
self.body.append('\n@caption{')
|
||||||
else:
|
else:
|
||||||
self.builder.warn('caption not inside a figure.',
|
logger.warning('caption not inside a figure.',
|
||||||
(self.curfilestack[-1], node.line))
|
location=(self.curfilestack[-1], node.line))
|
||||||
|
|
||||||
def depart_caption(self, node):
|
def depart_caption(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
@ -1434,13 +1437,13 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
|||||||
|
|
||||||
def unimplemented_visit(self, node):
|
def unimplemented_visit(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
self.builder.warn("unimplemented node type: %r" % node,
|
logger.warning("unimplemented node type: %r", node,
|
||||||
(self.curfilestack[-1], node.line))
|
location=(self.curfilestack[-1], node.line))
|
||||||
|
|
||||||
def unknown_visit(self, node):
|
def unknown_visit(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
self.builder.warn("unknown node type: %r" % node,
|
logger.warning("unknown node type: %r", node,
|
||||||
(self.curfilestack[-1], node.line))
|
location=(self.curfilestack[-1], node.line))
|
||||||
|
|
||||||
def unknown_departure(self, node):
|
def unknown_departure(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
@ -1756,9 +1759,9 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
|||||||
|
|
||||||
def visit_math(self, node):
|
def visit_math(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
self.builder.warn('using "math" markup without a Sphinx math extension '
|
logger.warning('using "math" markup without a Sphinx math extension '
|
||||||
'active, please use one of the math extensions '
|
'active, please use one of the math extensions '
|
||||||
'described at http://sphinx-doc.org/ext/math.html')
|
'described at http://sphinx-doc.org/ext/math.html')
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
visit_math_block = visit_math
|
visit_math_block = visit_math
|
||||||
|
@ -22,12 +22,15 @@ from docutils.utils import column_width
|
|||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.deprecation import RemovedInSphinx16Warning
|
from sphinx.deprecation import RemovedInSphinx16Warning
|
||||||
from sphinx.locale import admonitionlabels, _
|
from sphinx.locale import admonitionlabels, _
|
||||||
|
from sphinx.util import logging
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Callable, Tuple, Union # NOQA
|
from typing import Any, Callable, Tuple, Union # NOQA
|
||||||
from sphinx.builders.text import TextBuilder # NOQA
|
from sphinx.builders.text import TextBuilder # NOQA
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class TextWrapper(textwrap.TextWrapper):
|
class TextWrapper(textwrap.TextWrapper):
|
||||||
"""Custom subclass that uses a different word separator regex."""
|
"""Custom subclass that uses a different word separator regex."""
|
||||||
@ -1174,10 +1177,10 @@ class TextTranslator(nodes.NodeVisitor):
|
|||||||
|
|
||||||
def visit_math(self, node):
|
def visit_math(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
self.builder.warn('using "math" markup without a Sphinx math extension '
|
logger.warning('using "math" markup without a Sphinx math extension '
|
||||||
'active, please use one of the math extensions '
|
'active, please use one of the math extensions '
|
||||||
'described at http://sphinx-doc.org/ext/math.html',
|
'described at http://sphinx-doc.org/ext/math.html',
|
||||||
(self.builder.current_docname, node.line))
|
location=(self.builder.current_docname, node.line))
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
visit_math_block = visit_math
|
visit_math_block = visit_math
|
||||||
|
@ -47,26 +47,6 @@ def test_emit_with_nonascii_name_node(app, status, warning):
|
|||||||
app.emit('my_event', node)
|
app.emit('my_event', node)
|
||||||
|
|
||||||
|
|
||||||
@with_app()
|
|
||||||
def test_output(app, status, warning):
|
|
||||||
# info with newline
|
|
||||||
status.truncate(0) # __init__ writes to status
|
|
||||||
status.seek(0)
|
|
||||||
app.info("Nothing here...")
|
|
||||||
assert status.getvalue() == "Nothing here...\n"
|
|
||||||
# info without newline
|
|
||||||
status.truncate(0)
|
|
||||||
status.seek(0)
|
|
||||||
app.info("Nothing here...", True)
|
|
||||||
assert status.getvalue() == "Nothing here..."
|
|
||||||
|
|
||||||
# warning
|
|
||||||
old_count = app._warncount
|
|
||||||
app.warn("Bad news!")
|
|
||||||
assert strip_escseq(warning.getvalue()) == "WARNING: Bad news!\n"
|
|
||||||
assert app._warncount == old_count + 1
|
|
||||||
|
|
||||||
|
|
||||||
@with_app()
|
@with_app()
|
||||||
def test_extensions(app, status, warning):
|
def test_extensions(app, status, warning):
|
||||||
app.setup_extension('shutil')
|
app.setup_extension('shutil')
|
||||||
|
@ -9,35 +9,26 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from six import PY3
|
from six import StringIO
|
||||||
|
|
||||||
from util import TestApp, remove_unicode_literals, path
|
from util import TestApp, path
|
||||||
|
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
from sphinx.builders.latex import LaTeXBuilder
|
from sphinx.builders.latex import LaTeXBuilder
|
||||||
|
|
||||||
app = env = None
|
app = env = None
|
||||||
warnings = []
|
|
||||||
|
|
||||||
|
|
||||||
def setup_module():
|
def setup_module():
|
||||||
global app, env
|
global app, env
|
||||||
app = TestApp(srcdir='root-envtest')
|
app = TestApp(srcdir='root-envtest', warning=StringIO())
|
||||||
env = app.env
|
env = app.env
|
||||||
env.set_warnfunc(lambda *args, **kwargs: warnings.append(args))
|
|
||||||
|
|
||||||
|
|
||||||
def teardown_module():
|
def teardown_module():
|
||||||
app.cleanup()
|
app.cleanup()
|
||||||
|
|
||||||
|
|
||||||
def warning_emitted(file, text):
|
|
||||||
for warning in warnings:
|
|
||||||
if len(warning) == 2 and file in warning[1] and text in warning[0]:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
# Tests are run in the order they appear in the file, therefore we can
|
# Tests are run in the order they appear in the file, therefore we can
|
||||||
# afford to not run update() in the setup but in its own test
|
# afford to not run update() in the setup but in its own test
|
||||||
|
|
||||||
@ -49,12 +40,12 @@ def test_first_update():
|
|||||||
|
|
||||||
|
|
||||||
def test_images():
|
def test_images():
|
||||||
assert warning_emitted('images', 'image file not readable: foo.png')
|
assert ('image file not readable: foo.png'
|
||||||
assert warning_emitted('images', 'nonlocal image URI found: '
|
in app._warning.getvalue())
|
||||||
'http://www.python.org/logo.png')
|
assert ('nonlocal image URI found: http://www.python.org/logo.png'
|
||||||
|
in app._warning.getvalue())
|
||||||
|
|
||||||
tree = env.get_doctree('images')
|
tree = env.get_doctree('images')
|
||||||
app._warning.reset()
|
|
||||||
htmlbuilder = StandaloneHTMLBuilder(app)
|
htmlbuilder = StandaloneHTMLBuilder(app)
|
||||||
htmlbuilder.imgpath = 'dummy'
|
htmlbuilder.imgpath = 'dummy'
|
||||||
htmlbuilder.post_process_images(tree)
|
htmlbuilder.post_process_images(tree)
|
||||||
@ -64,7 +55,6 @@ def test_images():
|
|||||||
assert set(htmlbuilder.images.values()) == \
|
assert set(htmlbuilder.images.values()) == \
|
||||||
set(['img.png', 'img1.png', 'simg.png', 'svgimg.svg', 'img.foo.png'])
|
set(['img.png', 'img1.png', 'simg.png', 'svgimg.svg', 'img.foo.png'])
|
||||||
|
|
||||||
app._warning.reset()
|
|
||||||
latexbuilder = LaTeXBuilder(app)
|
latexbuilder = LaTeXBuilder(app)
|
||||||
latexbuilder.post_process_images(tree)
|
latexbuilder.post_process_images(tree)
|
||||||
assert set(latexbuilder.images.keys()) == \
|
assert set(latexbuilder.images.keys()) == \
|
||||||
|
@ -296,9 +296,10 @@ def test_output_with_unencodable_char(app, status, warning):
|
|||||||
self.stream.write(object.encode('cp1252').decode('cp1252'))
|
self.stream.write(object.encode('cp1252').decode('cp1252'))
|
||||||
|
|
||||||
logging.setup(app, StreamWriter(status), warning)
|
logging.setup(app, StreamWriter(status), warning)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# info with UnicodeEncodeError
|
# info with UnicodeEncodeError
|
||||||
status.truncate(0)
|
status.truncate(0)
|
||||||
status.seek(0)
|
status.seek(0)
|
||||||
app.info(u"unicode \u206d...")
|
logger.info(u"unicode \u206d...")
|
||||||
assert status.getvalue() == "unicode ?...\n"
|
assert status.getvalue() == "unicode ?...\n"
|
||||||
|
Loading…
Reference in New Issue
Block a user