diff --git a/CHANGES b/CHANGES
index 0367be1a0..21d0f72c3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -94,9 +94,20 @@ Release 1.0 (in development)
* Added ``htmltitle`` block in layout template.
-Release 0.6.4 (in development)
+Release 0.6.5 (in development)
==============================
+* #321: Fix link generation in the LaTeX builder.
+
+
+Release 0.6.4 (Jan 12, 2010)
+============================
+
+* Improve the handling of non-Unicode strings in the configuration.
+
+* #316: Catch OSErrors occurring when calling graphviz with
+ arguments it doesn't understand.
+
* Restore compatibility with Pygments >= 1.2.
* #295: Fix escaping of hyperref targets in LaTeX output.
diff --git a/doc/_templates/index.html b/doc/_templates/index.html
index 0f4d4c641..a68a62514 100644
--- a/doc/_templates/index.html
+++ b/doc/_templates/index.html
@@ -46,8 +46,10 @@
The Python documentation and
this page are different examples of Sphinx in use.
- You can also download a PDF version
- of the Sphinx documentation, generated from the LaTeX Sphinx produces.
+ You can also download PDF versions of the Sphinx documentation:
+ a version generated from
+ the LaTeX Sphinx produces, and a
+ version generated by rst2pdf.
For examples of how Sphinx source files look, use the “Show source”
diff --git a/doc/faq.rst b/doc/faq.rst
index 05b39ef4d..81204c08d 100644
--- a/doc/faq.rst
+++ b/doc/faq.rst
@@ -63,6 +63,39 @@ github pages
`_ to prepare
Sphinx HTML output.
+Google Analytics
+ You can use a custom ``layout.html`` template, like this:
+
+ .. code-block:: html+django
+
+ {% extends "!layout.html" %}
+
+ {%- block extrahead %}
+ {{ super() }}
+
+ {% endblock %}
+
+ {% block footer %}
+ {{ super() }}
+
+ {% endblock %}
+
.. _api role: http://git.savannah.gnu.org/cgit/kenozooid.git/tree/doc/extapi.py
.. _xhtml to reST: http://docutils.sourceforge.net/sandbox/xhtml2rest/xhtml2rest.py
diff --git a/setup.py b/setup.py
index 981270c88..aedfb8e78 100644
--- a/setup.py
+++ b/setup.py
@@ -21,19 +21,20 @@ Sphinx uses reStructuredText as its markup language, and many of its strengths
come from the power and straightforwardness of reStructuredText and its
parsing and translating suite, the Docutils.
-Although it is still under constant development, the following features
-are already present, work fine and can be seen "in action" in the Python docs:
+Among its features are the following:
-* Output formats: HTML (including Windows HTML Help), plain text and LaTeX,
- for printable PDF versions
+* Output formats: HTML (including derivative formats such as HTML Help, Epub
+ and Qt Help), plain text and LaTeX or direct PDF output using rst2pdf
* Extensive cross-references: semantic markup and automatic links
for functions, classes, glossary terms and similar pieces of information
* Hierarchical structure: easy definition of a document tree, with automatic
links to siblings, parents and children
* Automatic indices: general index as well as a module index
* Code handling: automatic highlighting using the Pygments highlighter
+* Flexible HTML output using the Jinja 2 templating engine
* Various extensions are available, e.g. for automatic testing of snippets
- and inclusion of appropriately formatted docstrings.
+ and inclusion of appropriately formatted docstrings
+* Setuptools integration
A development egg can be found `here
`_.
diff --git a/sphinx/application.py b/sphinx/application.py
index f95c5fe3b..395a21629 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -98,6 +98,7 @@ class Sphinx(object):
# read config
self.tags = Tags(tags)
self.config = Config(confdir, CONFIG_FILENAME, confoverrides, self.tags)
+ self.config.check_unicode(self.warn)
# load all extension modules
for extension in self.config.extensions:
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index cb800556c..a56919dbd 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -72,7 +72,8 @@ class StandaloneHTMLBuilder(Builder):
embedded = False # for things like HTML help or Qt help: suppresses sidebar
# This is a class attribute because it is mutated by Sphinx.add_javascript.
- script_files = ['_static/jquery.js', '_static/doctools.js']
+ script_files = ['_static/jquery.js', '_static/underscore.js',
+ '_static/doctools.js']
# Dito for this one.
css_files = []
@@ -731,7 +732,14 @@ class StandaloneHTMLBuilder(Builder):
self.app.emit('html-page-context', pagename, templatename,
ctx, event_arg)
- output = self.templates.render(templatename, ctx)
+ try:
+ output = self.templates.render(templatename, ctx)
+ except UnicodeError:
+ self.warn("a Unicode error occurred when rendering the page %s. "
+ "Please make sure all config values that contain "
+ "non-ASCII content are Unicode strings." % pagename)
+ return
+
if not outfilename:
outfilename = self.get_outfilename(pagename)
# outfilename's path is in general different from self.outdir
diff --git a/sphinx/builders/latex.py b/sphinx/builders/latex.py
index 0db30d553..751bf28cd 100644
--- a/sphinx/builders/latex.py
+++ b/sphinx/builders/latex.py
@@ -102,7 +102,13 @@ class LaTeXBuilder(Builder):
doctree.settings.title = title
doctree.settings.docname = docname
doctree.settings.docclass = docclass
- docwriter.write(doctree, destination)
+ try:
+ docwriter.write(doctree, destination)
+ except UnicodeError:
+ self.warn("a Unicode error occurred when writing the output. "
+ "Please make sure all config values that contain "
+ "non-ASCII content are Unicode strings.")
+ return
self.info("done")
def assemble_doctree(self, indexfile, toctree_only, appendices):
diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py
index 8a069b325..dc3269e23 100644
--- a/sphinx/cmdline.py
+++ b/sphinx/cmdline.py
@@ -198,10 +198,13 @@ def main(argv):
tbpath = save_traceback()
print >>error, red('The full traceback has been saved '
'in %s, if you want to report the '
- 'issue to the author.' % tbpath)
+ 'issue to the developers.' % tbpath)
print >>error, ('Please also report this if it was a user '
'error, so that a better error message '
'can be provided next time.')
- print >>error, ('Send reports to sphinx-dev@googlegroups.com. '
- 'Thanks!')
+ print >>error, (
+ 'Either send bugs to the mailing list at '
+ ',\n'
+ 'or report them in the tracker at '
+ '. Thanks!')
return 1
diff --git a/sphinx/config.py b/sphinx/config.py
index 23e5698b1..6cf8a270b 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -10,9 +10,13 @@
"""
import os
+import re
from os import path
from sphinx.util import make_filename
+from sphinx.errors import ConfigError
+
+nonascii_re = re.compile(r'[\x80-\xff]')
class Config(object):
@@ -140,20 +144,35 @@ class Config(object):
self.values = Config.config_values.copy()
config = {}
if dirname is not None:
- config['__file__'] = path.join(dirname, filename)
+ config_file = path.join(dirname, filename)
+ config['__file__'] = config_file
config['tags'] = tags
olddir = os.getcwd()
try:
- os.chdir(dirname)
- execfile(config['__file__'], config)
+ try:
+ os.chdir(dirname)
+ execfile(config['__file__'], config)
+ except SyntaxError, err:
+ raise ConfigError('There is a syntax error in your '
+ 'configuration file: ' + str(err))
finally:
os.chdir(olddir)
+
self._raw_config = config
# these two must be preinitialized because extensions can add their
# own config values
self.setup = config.get('setup', None)
self.extensions = config.get('extensions', [])
+ def check_unicode(self, warn):
+ # check all string values for non-ASCII characters in
+ # bytestrings, since that can
+ for name, value in self._raw_config.iteritems():
+ if isinstance(value, str) and nonascii_re.search(value):
+ warn('the config value %r is set to a string with non-ASCII '
+ 'characters; this can lead to Unicode errors occurring. '
+ 'Please use Unicode strings, e.g. u"Content".' % name)
+
def init_values(self):
config = self._raw_config
for valname, value in self.overrides.iteritems():
diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py
index 4afbcdbfc..40f63e0be 100644
--- a/sphinx/domains/std.py
+++ b/sphinx/domains/std.py
@@ -369,7 +369,7 @@ class StandardDomain(Domain):
docname, labelid = self.data['objects'].get((typ, target), ('', ''))
if not docname:
if typ == 'term':
- env.warn(node['refdoc'],
+ env.warn(node.get('refdoc', fromdocname),
'term not in glossary: %s' % target, node.line)
return None
else:
diff --git a/sphinx/environment.py b/sphinx/environment.py
index 38be61e43..dc5059369 100644
--- a/sphinx/environment.py
+++ b/sphinx/environment.py
@@ -1222,6 +1222,7 @@ class BuildEnvironment:
typ = node['reftype']
target = node['reftarget']
+ refdoc = node.get('refdoc', fromdocname)
try:
if node.has_key('refdomain') and node['refdomain']:
@@ -1240,7 +1241,7 @@ class BuildEnvironment:
docname, labelid = self.anonlabels.get(target, ('',''))
sectname = node.astext()
if not docname:
- self.warn(node['refdoc'], 'undefined label: %s' %
+ self.warn(refdoc, 'undefined label: %s' %
target, node.line)
else:
# reference to named label; the final node will
@@ -1248,8 +1249,7 @@ class BuildEnvironment:
docname, labelid, sectname = self.labels.get(target,
('','',''))
if not docname:
- self.warn(
- node['refdoc'],
+ self.warn(refdoc,
'undefined label: %s' % target + ' -- if you '
'don\'t give a link caption the label must '
'precede a section header.', node.line)
@@ -1273,9 +1273,9 @@ class BuildEnvironment:
elif typ == 'doc':
# directly reference to document by source name;
# can be absolute or relative
- docname = docname_join(node['refdoc'], target)
+ docname = docname_join(refdoc, target)
if docname not in self.all_docs:
- self.warn(node['refdoc'],
+ self.warn(refdoc,
'unknown document: %s' % docname, node.line)
else:
if node['refexplicit']:
@@ -1300,8 +1300,7 @@ class BuildEnvironment:
# keywords are oddballs: they are referenced by named labels
docname, labelid, _ = self.labels.get(target, ('','',''))
if not docname:
- #self.warn(node['refdoc'],
- # 'unknown keyword: %s' % target)
+ #self.warn(refdoc, 'unknown keyword: %s' % target)
pass
else:
newnode = make_refnode(builder, fromdocname, docname,
diff --git a/sphinx/errors.py b/sphinx/errors.py
index ca70fe4b2..6e8c4e1c6 100644
--- a/sphinx/errors.py
+++ b/sphinx/errors.py
@@ -44,6 +44,10 @@ class ExtensionError(SphinxError):
return parent_str
+class ConfigError(SphinxError):
+ category = 'Configuration error'
+
+
class ThemeError(SphinxError):
category = 'Theme error'
diff --git a/sphinx/ext/autosummary/templates/autosummary/module.rst b/sphinx/ext/autosummary/templates/autosummary/module.rst
index cc76c9e00..c14456ba1 100644
--- a/sphinx/ext/autosummary/templates/autosummary/module.rst
+++ b/sphinx/ext/autosummary/templates/autosummary/module.rst
@@ -30,7 +30,7 @@
.. rubric:: Exceptions
.. autosummary::
- {% for item in classes %}
+ {% for item in exceptions %}
{{ item }}
{%- endfor %}
{% endif %}
diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py
index 2f78d0887..3cd069c61 100644
--- a/sphinx/ext/graphviz.py
+++ b/sphinx/ext/graphviz.py
@@ -24,7 +24,7 @@ from docutils import nodes
from docutils.parsers.rst import directives
from sphinx.errors import SphinxError
-from sphinx.util import ensuredir, ENOENT
+from sphinx.util import ensuredir, ENOENT, EPIPE
from sphinx.util.compat import Directive
@@ -113,6 +113,10 @@ def render_dot(self, code, options, format, prefix='graphviz'):
ensuredir(path.dirname(outfn))
+ # graphviz expects UTF-8 by default
+ if isinstance(code, unicode):
+ code = code.encode('utf-8')
+
dot_args = [self.builder.config.graphviz_dot]
dot_args.extend(self.builder.config.graphviz_dot_args)
dot_args.extend(options)
@@ -129,10 +133,17 @@ def render_dot(self, code, options, format, prefix='graphviz'):
self.builder.config.graphviz_dot)
self.builder._graphviz_warned_dot = True
return None, None
- # graphviz expects UTF-8 by default
- if isinstance(code, unicode):
- code = code.encode('utf-8')
- stdout, stderr = p.communicate(code)
+ try:
+ # Graphviz may close standard input when an error occurs,
+ # resulting in a broken pipe on communicate()
+ stdout, stderr = p.communicate(code)
+ except OSError, err:
+ if err.errno != EPIPE:
+ raise
+ # in this case, read the standard output and standard error streams
+ # directly, to get the error message(s)
+ stdout, stderr = p.stdout.read(), p.stderr.read()
+ p.wait()
if p.returncode != 0:
raise GraphvizError('dot exited with error:\n[stderr]\n%s\n'
'[stdout]\n%s' % (stderr, stdout))
diff --git a/sphinx/themes/basic/static/doctools.js b/sphinx/themes/basic/static/doctools.js
index bf3375ff2..e91c4f3eb 100644
--- a/sphinx/themes/basic/static/doctools.js
+++ b/sphinx/themes/basic/static/doctools.js
@@ -9,6 +9,11 @@
*
*/
+/**
+ * select a different prefix for underscore
+ */
+$u = _.noConflict();
+
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
@@ -54,7 +59,7 @@ jQuery.getQueryParameters = function(s) {
result[key] = [value];
}
return result;
-}
+};
/**
* small function to check if an array contains
@@ -66,7 +71,7 @@ jQuery.contains = function(arr, item) {
return true;
}
return false;
-}
+};
/**
* highlight a given string on a jquery object by wrapping it in
@@ -96,7 +101,7 @@ jQuery.fn.highlightText = function(text, className) {
return this.each(function() {
highlight(this);
});
-}
+};
/**
* Small JavaScript module for the documentation.
diff --git a/sphinx/themes/basic/static/searchtools.js b/sphinx/themes/basic/static/searchtools.js
index 67bf695d5..c12471063 100644
--- a/sphinx/themes/basic/static/searchtools.js
+++ b/sphinx/themes/basic/static/searchtools.js
@@ -312,7 +312,7 @@ var Search = {
var tmp = query.split(/\s+/);
var object = (tmp.length == 1) ? tmp[0].toLowerCase() : null;
for (var i = 0; i < tmp.length; i++) {
- if (stopwords.indexOf(tmp[i]) != -1 || tmp[i].match(/^\d+$/)) {
+ if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/)) {
// skip this word
continue;
}
diff --git a/sphinx/themes/basic/static/underscore.js b/sphinx/themes/basic/static/underscore.js
new file mode 100644
index 000000000..9146e0860
--- /dev/null
+++ b/sphinx/themes/basic/static/underscore.js
@@ -0,0 +1,16 @@
+(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;gf?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)});
+return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length);
+var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false;
+if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length==
+0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&&
+a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g,
+" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments);
+o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})();
diff --git a/sphinx/themes/default/static/default.css_t b/sphinx/themes/default/static/default.css_t
index fb9fbe898..cddc85f72 100644
--- a/sphinx/themes/default/static/default.css_t
+++ b/sphinx/themes/default/static/default.css_t
@@ -210,6 +210,18 @@ div.admonition p.admonition-title + p {
display: inline;
}
+div.admonition p {
+ margin-bottom: 5px;
+}
+
+div.admonition pre {
+ margin-bottom: 5px;
+}
+
+div.admonition ul, div.admonition ol {
+ margin-bottom: 5px;
+}
+
div.note {
background-color: #eee;
border: 1px solid #ccc;
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index bd263545d..e6c0a661c 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -34,6 +34,7 @@ from sphinx.errors import PycodeError
# Errnos that we need.
EEXIST = getattr(errno, 'EEXIST', 0)
ENOENT = getattr(errno, 'ENOENT', 0)
+EPIPE = getattr(errno, 'EPIPE', 0)
# Generally useful regular expressions.
ws_re = re.compile(r'\s+')
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index eb8128ba3..ba7de6249 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -1046,13 +1046,15 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.body.append('\\href{%s}{' % self.encode_uri(uri))
self.context.append('}')
elif uri.startswith('#'):
- self.body.append('\\hyperlink{%s}{' % uri[1:])
+ # references to labels
+ self.body.append('\\hyperlink{%s}{' % self.idescape(uri[1:]))
self.context.append('}')
elif uri.startswith('%'):
+ # references to documents or labels inside documents
hashindex = uri.find('#')
targetname = (hashindex == -1) and '--doc-' + uri[1:] \
or uri[hashindex+1:]
- self.body.append('\\hyperlink{%s}{' % targetname)
+ self.body.append('\\hyperlink{%s}{' % self.idescape(targetname))
self.context.append('}')
elif uri.startswith('@token'):
if self.in_production_list:
diff --git a/tests/test_config.py b/tests/test_config.py
index 426b808ea..0ccdd9091 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -12,7 +12,8 @@
from util import *
-from sphinx.application import ExtensionError
+from sphinx.config import Config
+from sphinx.errors import ExtensionError, ConfigError
@with_app(confoverrides={'master_doc': 'master', 'nonexisting_value': 'True',
@@ -77,3 +78,19 @@ def test_extension_values(app):
'html_title', 'x', True)
raises_msg(ExtensionError, 'already present', app.add_config_value,
'value_from_ext', 'x', True)
+
+
+@with_tempdir
+def test_errors_warnings(dir):
+ # test the error for syntax errors in the config file
+ write_file(dir / 'conf.py', 'project = \n')
+ raises_msg(ConfigError, 'conf.py', Config, dir, 'conf.py', {}, None)
+
+ # test the warning for bytestrings with non-ascii content
+ write_file(dir / 'conf.py', '# -*- coding: latin-1\nproject = "foo\xe4"\n')
+ cfg = Config(dir, 'conf.py', {}, None)
+ warned = [False]
+ def warn(msg):
+ warned[0] = True
+ cfg.check_unicode(warn)
+ assert warned[0]
diff --git a/utils/check_sources.py b/utils/check_sources.py
index ec7695d57..6f78c26e0 100755
--- a/utils/check_sources.py
+++ b/utils/check_sources.py
@@ -154,8 +154,7 @@ def check_whitespace_and_spelling(fn, lines):
yield lno+1, '"%s" used' % word
-bad_tags = ('', '', ''
- '', '', '', '', '', '', '', '