# Buggy code
def warn_and_replace(self, error):
    """Custom decoding error handler that warns and replaces."""
    linestart = error.object.rfind("\n", 0, error.start)
    lineend = error.object.find("\n", error.start)
    if lineend == -1:
        lineend = len(error.object)
    lineno = error.object.count("\n", 0, error.start) + 1
    self.warn(
        self.docname,
        "undecodable source characters, "
        'replacing with "?": %r'
        % (
            error.object[linestart + 1 : error.start]
            + ">>>"
            + error.object[error.start : error.end]
            + "<<<"
            + error.object[error.end : lineend]
        ),
        lineno,
    )
    return ("?", error.end)


# Traceback (UnicodeDecodeError)
#!python
# Sphinx version: 1.3a0
# Python version: 3.3.4
# Docutils version: 0.10 release
# Jinja2 version: 2.6
# Loaded extensions:
#   sphinx.ext.todo from C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\ext\todo.py
#   sphinx.ext.ifconfig from C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\ext\ifconfig.py
#   sphinx.ext.extlinks from C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\ext\extlinks.py
#   sphinx.ext.intersphinx from C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\ext\intersphinx.py
#   sphinx.ext.mathjax from C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\ext\mathjax.py
#   sphinx.ext.pngmath from C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\ext\pngmath.py
Traceback (most recent call last):
File "C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\cmdline.py", line 253, in main
app.build(force_all, filenames)
File "C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\application.py", line 223, in build
self.builder.build_update()
File "C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\builders\__init__.py", line 214, in build_update
'out of date' &amp;#37; len(to_build))
File "C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\builders\__init__.py", line 234, in build
purple, length):
File "C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\builders\__init__.py", line 134, in status_iterator
for item in iterable:
File "C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\environment.py", line 474, in update_generator
self.read_doc(docname, app=app)
File "C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\environment.py", line 621, in read_doc
pub.publish()
File "C:\Python33\lib\site-packages\docutils-0.10-py3.3.egg\docutils\core.py", line 217, in publish
self.settings)
File "C:\Python33\lib\site-packages\docutils-0.10-py3.3.egg\docutils\readers\__init__.py", line 71, in read
self.input = self.source.read()
File "C:\Python33\lib\site-packages\sphinx-1.3a0dev_20140728-py3.3.egg\sphinx\environment.py", line 601, in read
data = FileInput.read(self_)
File "C:\Python33\lib\site-packages\docutils-0.10-py3.3.egg\docutils\io.py", line 265, in read
data = self.source.read()
File "C:\Python33\lib\codecs.py", line 301, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
File "C:\Python33\lib\encodings\utf_8_sig.py", line 69, in _buffer_decode
return codecs.utf_8_decode(input, errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbb in position 760: invalid start byte

# Fixed code
def warn_and_replace(self, error):
    """Custom decoding error handler that warns and replaces."""
    linestart = error.object.rfind(b"\n", 0, error.start)
    lineend = error.object.find(b"\n", error.start)
    if lineend == -1:
        lineend = len(error.object)
    lineno = error.object.count(b"\n", 0, error.start) + 1
    self.warn(
        self.docname,
        "undecodable source characters, "
        'replacing with "?": %r'
        % (
            error.object[linestart + 1 : error.start]
            + b">>>"
            + error.object[error.start : error.end]
            + b"<<<"
            + error.object[error.end : lineend]
        ),
        lineno,
    )
    return ("?", error.end)