Repository: adamchainz/blacken-docs (language: python)

Issue:
Support sphinx.ext.doctest directives
I have a project where most of the reStructuredText python source is in a `.. testcode:: python` block instead of `.. code-block:: python`.  Can support be added for the `testcode` block, and potentially the `doctest` one too?

https://www.sphinx-doc.org/en/master/usage/extensions/doctest.html



Discussion / hints:
there's already [a bunch of others](https://github.com/asottile/blacken-docs/blob/67dd1372cc3db5c2f15399c70bf344d0d02ac320/blacken_docs.py#L23) if you're looking for a place to augment

patches welcome!

Fix patch:
diff --git a/blacken_docs.py b/blacken_docs.py
index dc98c34..ce112ad 100644
--- a/blacken_docs.py
+++ b/blacken_docs.py
@@ -27,9 +27,14 @@
 )
 PY_LANGS = '(python|py|sage|python3|py3|numpy)'
 BLOCK_TYPES = '(code|code-block|sourcecode|ipython)'
+DOCTEST_TYPES = '(testsetup|testcleanup|testcode)'
 RST_RE = re.compile(
     rf'(?P<before>'
-    rf'^(?P<indent> *)\.\. (jupyter-execute::|{BLOCK_TYPES}:: {PY_LANGS})\n'
+    rf'^(?P<indent> *)\.\. ('
+    rf'jupyter-execute::|'
+    rf'{BLOCK_TYPES}:: {PY_LANGS}|'
+    rf'{DOCTEST_TYPES}::.*'
+    rf')\n'
     rf'((?P=indent) +:.*\n)*'
     rf'\n*'
     rf')'
@@ -38,7 +43,7 @@
 )
 RST_PYCON_RE = re.compile(
     r'(?P<before>'
-    r'(?P<indent> *)\.\. (code|code-block):: pycon\n'
+    r'(?P<indent> *)\.\. ((code|code-block):: pycon|doctest::.*)\n'
     r'((?P=indent) +:.*\n)*'
     r'\n*'
     r')'


Test patch:
diff --git a/tests/blacken_docs_test.py b/tests/blacken_docs_test.py
index 32518bc..0c4d8e3 100644
--- a/tests/blacken_docs_test.py
+++ b/tests/blacken_docs_test.py
@@ -153,6 +153,51 @@ def test_format_src_rst():
     )
 
 
+def test_format_src_rst_sphinx_doctest():
+    before = (
+        '.. testsetup:: group1\n'
+        '\n'
+        '   import parrot  \n'
+        '   mock = SomeMock( )\n'
+        '\n'
+        '.. testcleanup:: group1\n'
+        '\n'
+        '   mock.stop( )\n'
+        '\n'
+        '.. doctest:: group1\n'
+        '\n'
+        '   >>> parrot.voom( 3000 )\n'
+        '   This parrot wouldn\'t voom if you put 3000 volts through it!\n'
+        '\n'
+        '.. testcode::\n'
+        '\n'
+        '   parrot.voom( 3000 )\n'
+        '\n'
+    )
+    after, _ = blacken_docs.format_str(before, BLACK_MODE)
+    assert after == (
+        '.. testsetup:: group1\n'
+        '\n'
+        '   import parrot\n'
+        '\n'
+        '   mock = SomeMock()\n'
+        '\n'
+        '.. testcleanup:: group1\n'
+        '\n'
+        '   mock.stop()\n'
+        '\n'
+        '.. doctest:: group1\n'
+        '\n'
+        '   >>> parrot.voom(3000)\n'
+        '   This parrot wouldn\'t voom if you put 3000 volts through it!\n'
+        '\n'
+        '.. testcode::\n'
+        '\n'
+        '   parrot.voom(3000)\n'
+        '\n'
+    )
+
+
 def test_format_src_rst_indented():
     before = (
         '.. versionadded:: 3.1\n'