Python 3 and b'\x92'.decode('latin1')
<p>I'm getting results I didn't expect from decoding b'\x92' with the latin1 codec. See the session below:</p>

<pre><code>Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
&gt;&gt;&gt; b'\xa3'.decode('latin1').encode('ascii', 'namereplace')
b'\\N{POUND SIGN}'
&gt;&gt;&gt; b'\x92'.decode('latin1').encode('ascii', 'namereplace')
b'\\x92'
&gt;&gt;&gt; ord(b'\x92'.decode('latin1'))
146
</code></pre>

<p>The result decoding b'\xa3' gave me exactly what I was expecting. But the two results for b'\x92' were not what I expected. I was expecting b'\x92'.decode('latin1') to result in U+2018, but it seems to be returning U+0092.</p>

<p>What am I missing?</p>

<p>I just want to make clear that you're not encoding anything here. </p>

<p><code>xa3</code> has a ordinal value of 163 (0xa3 in hexadecimal). Since that ordinal is not seven bits, it can't be encoded into ascii. Your handler for errors just replaces the Unicode Character into the name of the character. The Unicode Character 163 maps to Â£.</p>

<p>'\x92' on the other hand, has an ordinal value of 146. According to <a href="https://en.wikipedia.org/wiki/List_of_Unicode_characters#Control_codes" rel="nofollow">this Wikipedia Article</a>, the character isn't printable - it's a privately used control code in the C2 space. This explains why it's name is simply the literal <code>'\\x92'</code>.</p>

<p>As an aside, if you need the name of the character, it's much better to do it like this:</p>

<pre><code>import unicodedata
print unicodedata.name(u'\xa3')
</code></pre>

python python-3.x unicode python-unicode