Подтвердить что ты не робот

Можно ли иметь эллипсис в начале строки в доктрине Python?

Уроки Python классные. Позвольте мне начать с простого примера:

def foo():
  """
  >>> foo()
  hello world
  """
  print "hello world"

Теперь предположим, что какая-то часть несколько изменяет, например, потому что это значение времени или случайное число. В общем, доктрины позволяют мне задавать подстановочный знак, используя опцию + ELLIPSIS.

Это отлично работает, когда, например, "мир" представляет собой переменную строку:

def foo():
  """
  >>> foo()   # doctest: +ELLIPSIS
  hello ...
  """
  print "hello world"

В моем случае, однако, переменная строка находится в начале строки:

def foo():
  """
  >>> foo() # doctest: +ELLIPSIS
  ... world
  """
  print "hello world"

что плохо, потому что 3 точки в начале интерпретируются как символы продолжения строки, а не как многоточие для вывода. Поэтому этот тест не выполняется:

Failed example:
    foo() # doctest: +ELLIPSIS
    world
Expected nothing
Got:
    hello world

Итак, теперь я могу переписать свой вариант, чтобы иметь переменную часть в другом месте, но есть ли способ научить доктрине, что три точки в начале строки являются многоточиями?

4b9b3361

Ответ 1

Вот вам быстрый и грязный хак для вас:

def foo():
    """
    >>> foo() # doctest: +ELLIPSIS
    [...] world
    """
    print "hello world"

if __name__ == "__main__":
    import doctest

    OC = doctest.OutputChecker
    class AEOutputChecker(OC):
        def check_output(self, want, got, optionflags):
            from re import sub
            if optionflags & doctest.ELLIPSIS:
                want = sub(r'\[\.\.\.\]', '...', want)
            return OC.check_output(self, want, got, optionflags)

    doctest.OutputChecker = AEOutputChecker
    doctest.testmod()

Это все еще понимает нормальный (...) эллипс, но добавляет новый ([...]), который не вызывает неоднозначность начала строки.

Было бы очень сложно, если бы доктрист угадал, ожидает ли ожидаемое продолжение линии или начнет ли она эллипсис линии, - теоретически можно сделать, если вы подклассифицируете DocTestParser для выполнения этой работы, но это, вероятно, не будет весело.

В сложных ситуациях вы, вероятно, должны свернуть свой собственный DocTestRunner, который будет использовать новый OutputChecker, и использовать это вместо обычного testmod, но это должно выполняться в простых сценариях.

Ответ 2

Вот несколько более простой способ сделать это: Просто напечатайте фиктивную строку перед строкой, которая начинается с неизвестного вывода.

Вот так:

def foo():
  """
  >>> print 'ignore'; foo() # doctest: +ELLIPSIS
  ignore... world
  """
  print "hello world"

Ответ 3

Вы можете обновить ELLIPSIS_MARKER для своего теста, чтобы ... не путался с точками продолжения строки:

def foo():
    """
    >>> import doctest
    >>> doctest.ELLIPSIS_MARKER = '-ignore-'
    >>> foo()
    hello world
    >>> foo() # doctest: +ELLIPSIS
    -ignore- world
    """
    print "hello world"

if __name__ == "__main__":
    import doctest
    doctest.testmod()


Отказ от ответственности: приведенный выше пример работает, когда doctests запускается как

$ py.test --doctest-module foo.py

или

$ python foo.py

Однако по причинам, которые я не понимаю, это не работает при запуске доктрин с помощью

$ python -m doctest foo.py