Usage

command-line interface

blackdoc tries to copy as much of the CLI of black as possible. This means that most calls to black can be directly translated to blackdoc:

To reformat specific files, use:

python -m blackdoc file1 file2 ...

while passing directories reformats all files in those directories that match the file format specified by --include and --exclude:

python -m blackdoc directory1 directory2 ...

mixing directories and files is also possible.

As an example, having a structure like:

directory
├── file.py
└── file.rst

with

# directory/file.py
"""
docstring with code.

doctests:
>>> s={ "a", "b","c", 'd', "e", "f", "e",
...     "f", "g",'h', "i", "j", "k",'l', 'm',
...                                          }

>>> s = (
...     "a"
...     + "b"
... )

>>> def f():
...     '''nested docstring
...
...     parameter documentation
...     '''
...
...     s = (
...         '''triple-quoted string'''
...     )
...

ipython:
In [1]: d= { "a": 0, "b": 1, "c": 2,
   ...: "d": 3, "e": 4, "f": 5, "g": 6,
   ...: "h": 7, "i": 8, "j": 9 }
"""
.. directory/file.rst
file with code:

.. code:: python

    def function_with_long_name(parameter1, parameter2,
          parameter3, *variable_args, **keyword_args):
        pass

more code:

.. code-block:: python

    for index, (value1, value2, value3, value4) in enumerate(zip(iterable1,
            iterable2, iterable3, iterable4)):
        pass

doctest code:

>>> 4*10
40
>>> a=1;print("abc:",a)
abc: 1
>>> # comment
... a=1
>>> @decorator
... def f():
...     pass

in a code block:

.. code:: python

   >>> ', '.join( ['15','30'] )
   15, 30

executed code:

.. ipython:: python

    keys = ('key1', 'key2')
    values = (15,4)

    mapping = dict(zip(keys, values))

    mapping

with explicit grouping:

.. ipython:: python

    In [1]: keys = ( 'key1', 'key2' )
       ...: values = {15, 4}

    In [2]: mapping = {key : value for key, value in zip( keys,values) }
       ...: mapping

with testcode:

.. testsetup::

   x = 'X'
   y =  "Y"

.. testcode::

   assert x==x
   assert x !=  y

.. testcleanup::

   print('test completed')

If we run

python -m blackdoc directory

we get

# directory/file.py
"""
docstring with code.

doctests:
>>> s = {
...     "a",
...     "b",
...     "c",
...     "d",
...     "e",
...     "f",
...     "e",
...     "f",
...     "g",
...     "h",
...     "i",
...     "j",
...     "k",
...     "l",
...     "m",
... }

>>> s = "a" + "b"

>>> def f():
...     '''nested docstring
...
...     parameter documentation
...     '''
...
...     s = '''triple-quoted string'''
...

ipython:
In [1]: d = {"a": 0, "b": 1, "c": 2, "d": 3, "e": 4, "f": 5, "g": 6, "h": 7, "i": 8, "j": 9}
"""
.. directory/file.rst
file with code:

.. code:: python

    def function_with_long_name(
        parameter1, parameter2, parameter3, *variable_args, **keyword_args
    ):
        pass

more code:

.. code-block:: python

    for index, (value1, value2, value3, value4) in enumerate(
        zip(iterable1, iterable2, iterable3, iterable4)
    ):
        pass

doctest code:

>>> 4 * 10
40
>>> a = 1
>>> print("abc:", a)
abc: 1

in a code block:

.. code:: python

   >>> ", ".join(["15", "30"])
   15, 30

executed code:

.. ipython:: python

    keys = ("key1", "key2")
    values = (15, 4)

    mapping = dict(zip(keys, values))

    mapping

with explicit grouping:

.. ipython:: python

    In [1]: keys = ("key1", "key2")
       ...: values = {15, 4}

    In [2]: mapping = {key: value for key, value in zip(keys, values)}
       ...: mapping

with testcode:

.. testsetup::

    x = "X"
    y = "Y"

.. testcode::

    assert x == x
    assert x != y

.. testcleanup::

    print("test completed")

If instead we run

python -m blackdoc --check directory

the result is:

would reformat directory/file.rst
would reformat directory/file.py
Oh no! 💥 💔 💥
2 files would be reformatted.

with a non-zero exit status.

pre-commit

The repository also defines a pre-commit hook:

hooks:
...
- repo: https://github.com/keewis/blackdoc
  rev: 3.8.0
  hooks:
  - id: blackdoc

It is recommended to pin black in order to avoid having different versions for each contributor. To automatically synchronize this pin with the version of the black hook, use the blackdoc-autoupdate-black hook:

hooks:
...
- repo: https://github.com/psf/black
  rev: 23.10.1
  hooks:
  - id: black
...
- repo: https://github.com/keewis/blackdoc
  rev: 3.8.0
  hooks:
  - id: blackdoc
    additional_dependencies: ["black==23.10.1"]
  - id: blackdoc-autoupdate-black

Note that this hook is not run on pre-commit autoupdate.