Тестирование на UnicodeDecodeError в Python 3 - PullRequest
3 голосов
/ 27 июля 2011

У меня есть следующий тест для функции, которая может принимать только текст Unicode в Python 2.x

def testNonUnicodeInput(self):
        """ Test falure on non-unicode input. """
        input = "foo".encode('utf-16')
        self.assertRaises(UnicodeDecodeError, myfunction, input)

Однако этот тест не пройден при запуске в Python 3.x. Я получаю:

AssertionError: UnicodeDecodeError not raised by myfunction

Я пытаюсь выяснить, как настроить тест, который будет продолжать работать в Python 2.x, но также будет работать после запуска через 2to3 в Python 3.x.

Вероятно, я должен заметить, что я выполняю в своей функции следующее, чтобы принудительно использовать Unicode:

def myfunction(input):
    """ myfunction only accepts unicode input. """
    ...
    try:
        source = unicode(source)
    except UnicodeDecodeError, e:
        # Customise error message while maintaining original trackback
        e.reason += '. -- Note: Myfunction only accepts unicode input!'
        raise
    ...

Конечно, это (вместе с тестом) проходит через 2to3 до запуска на Python 3.x. Я предполагаю, что на самом деле я хочу, чтобы в Python 3 не принимались строки байтов, что я и делал, сначала кодируя строку. Я не использовал utf-8 в качестве кодировки, потому что я понимаю, что это значение по умолчанию.

У кого-нибудь есть идеи по поводу согласованности здесь?

Ответы [ 2 ]

3 голосов
/ 27 июля 2011

Вам не нужно ничего делать со строками Python 3;они все Unicode.Просто проверьте isinstance (s, str).Или, если проблема заключается в обратном, вам следует использовать bytes.decode ().

Хорошо, способ вызвать UnicodeDecodeError в Python 3 и Python 2:

Python 3:

>>> "foo".encode('utf-16').decode('utf-8')
Traceback (most recent call last):
  File "<pyshell#61>", line 1, in <module>
"foo".encode('utf-16').decode('utf-8')
UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 0: unexpected code byte

Python 2:

>>> "foo".encode('utf-16').decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python26\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 0: unexpected code byte

Однако не уверен, что 2to3 автоматически преобразует строковый литерал в синтаксис b"foo".Если это произойдет, вам просто нужно вынуть b вручную или настроить его так или иначе игнорировать.

0 голосов
/ 28 июля 2011

Ну, я решил пока пропустить тест под Python 3.

if sys.version_info < (3, 0):
    input = "foo".encode('utf-16')
    self.assertRaises(UnicodeDecodeError, myfunction, input

Однако, если кто-то может предложить тест, который пройдет под Python 2 и 3, я открыт для предложений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...