Я использую mkdocs и mkdocstring для создания документации и включения примеров кода в строки документации. Я также использую doctest (через pytest --doctest-modules
), чтобы проверить все эти примеры.
Если я отформатирую свою документацию следующим образом:
"""
Recursively flattens a nested iterable (including strings!) and returns all elements in order left to right.
Examples:
--------
```
>>> [x for x in flatten([1,2,[3,4,[5],6],7,[8,9]])]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```
"""
Затем он хорошо отображается в документации, но doctest завершается с ошибкой:
Expected:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```
Got:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Это имеет смысл, поскольку doctest обрабатывает все до тех пор, пока не появится пустая строка, как ожидаемый результат, и стремится точно соответствовать
Если я отформатирую строку документации для doctest без блоков кода:
"""
Recursively flattens a nested iterable (including strings!) and returns all elements in order left to right.
Examples:
--------
>>> [x for x in flatten([1,2,[3,4,[5],6],7,[8,9]])]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
"""
затем doctest проходит, но документация отображается
[x для x в Flatten([1,2,[3,4,[5],6],7,[8,9]])][1, 2, 3, 4, 5, 6, 7, 8 , 9]
Если я отформатирую его с дополнительной пустой строкой перед концом кодового блока:
"""
Recursively flattens a nested iterable (including strings!) and returns all elements in order left to right.
Examples:
--------
```
>>> [x for x in flatten([1,2,[3,4,[5],6],7,[8,9]])]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```
"""
Затем документация проходит, но
Кто-нибудь знает лучшее решение?
🤔 А знаете ли вы, что...
В Python есть инструменты для создания графиков и визуализации данных, такие как библиотеки Matplotlib и Seaborn.
Исправление регулярного выражения, которое doctest использует для идентификации кодовых блоков, решило эту проблему. Документирую это здесь для тех, кто наткнется на это в будущем...
Поскольку я не хочу регулярно делать это в проектах (!), я создал pytest-doctest-mkdocstrings в качестве плагина pytest, чтобы делать это за меня, и включил некоторые дополнительные проверки работоспособности, параметры конфигурации и т. д.
pip install pytest-doctest-mkdocstrings
pytest --doctest-mdcodeblocks --doctest-modules --doctest-glob = "*.md"
Для тех, кто ищет здесь ответ в коде, который можно использовать самостоятельно, необходимо внести следующие изменения:
_MD_EXAMPLE_RE = re.compile(
r"""
# Source consists of a PS1 line followed by zero or more PS2 lines.
(?P<source>
(?:^(?P<indent> [ ]*) >>> .*) # PS1 line
(?:\n [ ]* \.\.\. .*)*) # PS2 lines
\n?
# Want consists of any non-blank lines that do not start with PS1.
(?P<want> (?:(?![ ]*$) # Not a blank line
(?![ ]*```) # Not end of a code block
(?![ ]*>>>) # Not a line starting with PS1
.+$\n? # But any other line
)*)
""",
re.MULTILINE | re.VERBOSE,
)
doctest.DocTestParser._EXAMPLE_RE = _MD_EXAMPLE_RE
Конкретно я включил (?![ ]*```) # Not end of a code block
в обозначение "хочу"
mkdocstrings (в частности, Griffe) поддерживает необработанные фрагменты pycon
в разделах «Примеры». Однако ваш раздел «Примеры», вероятно, не распознается как таковой из-за дополнительного двоеточия в конце заголовка (Examples:
). Попробуйте удалить его, а также обратные галочки:
"""
Recursively flattens a nested iterable (including strings!) and returns all elements in order left to right.
Examples
--------
>>> [x for x in flatten([1,2,[3,4,[5],6],7,[8,9]])]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
"""
Теперь, возможно, doctest все еще хочет пустую строку перед закрытием """
, не уверен.
Кроме того, обратите внимание, что я создал расширение Python-Markdown, которое распознает необработанный pycon
код где угодно, а не только в разделах «Примеры»: https://pawamoy.github.io/markdown-pycon/ (на данный момент доступно только спонсорам) письма).