Don't use unichr()
; it produces a unicode string with one character. Don't mix Unicode strings and byte strings (binary data), as this'll trigger implicit encoding or decoding. Here an implicit decode is triggered and fails.
Your codepoints are limited to values 0-255, so a simple chr()
will do:
stuff = re.sub("#([0-9A-Fa-f]{2})", lambda m: chr(int(m.group(0), 16)), stuff)