pytest не может обрабатывать Unicode в doctest в README под Python 2.7

У меня есть файл README.rst, содержащий несколько doctests для моей библиотеки Python. Все они работают, кроме последнего doctest, который выводит prints Unicode, закодированный в UTF-8:

Here is a failing example::

    >>> print(u'\xE5\xE9\xEE\xF8\xFC')
    åéîøü

(Использование print, а не просто строки, очень важно для моего фактического варианта использования, поскольку реальная строка содержит встроенные символы новой строки, и мне нужно показать, как выровнены элементы в разных строках.)

Выполнение pytest README.rst успешно работает с Python 3.6.5 и pytest 3.6.1, но в Python 2.7.10 происходит сбой с очень длинной трассировкой, которая заканчивается:

input = 'åéîøü
', errors = 'strict'

    def decode(input, errors='strict'):
>       return codecs.utftox.inidecode(input, errors, True)
E       UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py:16: UnicodeEncodeError

Установка setenv = LC_ALL=en_US.UTF-8 в tox.ini и запуск под tox ничего не меняет; также не добавляется doctest_encoding = utf-8 в раздел [pytest] tox.ini. Я не вижу вариантов doctest, имеющих отношение к моему тяжелому положению. Как мне добиться успешного запуска теста в Python 2.7?

Обновление: ошибка, вызывающая эту проблему, была исправлена ​​в pytest 3.6.2.


person jwodder    schedule 14.06.2018    source источник
comment
У меня работает с UTF-8 test.rst, даже если моя локаль ru_RU.KOI8-R. Без дополнительной настройки. Python 2.7.13, pytest 3.6.1. Пожалуйста, покажите неудачный пример.   -  person phd    schedule 14.06.2018
comment
@phd: добавлен пример. Я думаю, что ключевым моментом здесь может быть использование print.   -  person jwodder    schedule 14.06.2018


Ответы (1)


Да, print виноват. Самая интересная часть исключения заключается в следующем:

def getvalue(self):
    result = _SpoofOut.getvalue(self)
    if encoding:
        result = result.decode(encoding)

local/lib/python2.7/site-packages/_pytest/doctest.py:509:

pytest пытается декодировать юникод, поэтому Python сначала пытается закодировать его — и терпит неудачу. Я думаю, что это ошибка в pytest: он должен проверить, является ли result байтами или юникодом:

    if encoding and isinstance(result, bytes):
        result = result.decode(encoding)

Пожалуйста, сообщите об этом в систему отслеживания проблем pytest. Вы можете протестировать исправление, и если оно работает, вы можете отправить запрос на включение.

person phd    schedule 14.06.2018
comment
сообщено об ошибке и PR открыт; Благодарность! - person jwodder; 14.06.2018