Há um bug em python 2.x que é apenas python 3.x fixo. Na verdade, esse bug está mesmo no iconv do OS X (mas não no glibc).
Aqui está o que está acontecendo:
Python 2.x não reconhece pares substitutos UTF8 [1] como sendo inválidos (que é sua sequência de caracteres)
Isso deve seja tudo o que é necessário:
foo.decode('utf8').encode('utf8')
Mas graças a esse bug que eles não estão consertando, ele não pega pares substitutos.
Tente isso em python 2.xe depois em 3.x:
b'\xed\xbd\xbf'.decode('utf8')
Ele lançará um erro (corretamente) no último. Eles também não estão corrigindo isso no branch 2.x. Veja [2] e [3] para mais informações
[1] https://www.rfc-editor.org/rfc/ rfc3629#section-4
[2] http://bugs.python.org/issue9133
[3] http://bugs.python.org/issue8271#msg102209