Включить необработанный символ табуляции в doctest

#python #python-3.x #doctest

#python #python-3.x #doctest

Вопрос:

Я не могу понять, как избежать этой ошибки doctest:

 Failed example:
    print(test())
Expected:
        output
    <BLANKLINE>
Got:
        output
    <BLANKLINE>
  

Для этого кода

 def test():
    r'''Produce string according to specification.

    >>> print(test())
        output
    <BLANKLINE>
    '''
    return 'toutputn'
  

Я вставил литерал табуляции в исходный код, строка 5 впереди output .

Похоже на doctest (или строки документации python?) игнорирует этот литерал табуляции и преобразует его в четыре пробела.

Так называемое «ожидаемое» значение буквально не соответствует тому, что указывает мой источник.

Каково решение для этого?

Я не хочу заменять оператор печати на

 >>> test()
'toutputn'
  

Потому что огромная часть того, почему мне обычно нравятся doctests, заключается в том, что они демонстрируют примеры, и самая важная часть этой функции, которую я пишу, — это форма вывода.

Комментарии:

1. Вы уверены, что это не ваш редактор / IDE, заменяющий табуляции пробелами?

2. @snwflk да, да

3. Стоит отметить, что переполнение стека преобразует табуляцию в четыре пробела. Возможно, это то, о чем говорит @snwflk.

4. @wjandrea о да, я не заметил, что это позор. Однако на моем компьютере это определенно символ табуляции.

Ответ №1:

Вкладки в строке документа расширяются до 8 пробелов, но вкладки в выходных данных не расширяются.

Из документации doctest (курсив добавлен):

Все жесткие символы табуляции расширяются до пробелов с использованием табуляции с 8 столбцами. Табуляции в выходных данных, сгенерированных тестируемым кодом, не изменяются. Поскольку любые жесткие вкладки в выводе примера расширяются, это означает, что если вывод кода включает жесткие вкладки, единственный способ, которым может пройти doctest, — это если NORMALIZE_WHITESPACE действует опция или директива. Кроме того, тест можно переписать, чтобы получить выходные данные и сравнить их с ожидаемым значением как часть теста.Такая обработка вкладок в исходном коде была достигнута методом проб и ошибок и оказалась наименее подверженным ошибкам способом их обработки. Можно использовать другой алгоритм для обработки вкладок, написав пользовательский DocTestParser класс.

К сожалению, все примеры использования директив в документах doctest были искажены Sphinx. Вот как вы могли бы использовать NORMALIZE_WHITESPACE :

 def test():
    r'''Produce string according to specification.

    >>> print(test()) # doctest:  NORMALIZE_WHITESPACE
        output
    <BLANKLINE>
    '''
    return 'toutputn'
  

Обратите внимание, что это обрабатывает все пробельные символы как равные, а не отключает обработку табуляции. Отключение обработки табуляции абсурдно громоздко, и это невозможно через обычный интерфейс doctest — вам нужно будет создать подкласс DocTestParser , вручную переопределить синтаксический анализ doctest, затем создать экземпляры DocTestFinder , DocTestRunner , и ваш DocTestParser подкласс и вызвать их методы вручную.

Комментарии:

1. Это довольно обидно. Бесцеремонное «[это] оказалось наименее подверженным ошибкам способом их обработки» тоже довольно неприятно. В каких случаях обработка вкладок ожидаемым пользователем способом приведет к ошибкам?

2. Это предотвращает проверку a 't' против a ' '