black icon indicating copy to clipboard operation
black copied to clipboard

Documentation: mention tools that can do doctests formatting

Open KelSolaar opened this issue 2 years ago • 11 comments

Is your feature request related to a problem? Please describe.

Black currently does not format Doctests in Docstrings. This issues was reported in https://github.com/psf/black/issues/745 which was superseeded by https://github.com/psf/black/issues/144.

As the latter was closed though, nothing was done about the Doctests.

Describe the solution you'd like

I would be keen for black to format Doctest.

For example, given the following Python Doctests code:

    >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
    >>> LMS_to_LMS_p_callable = lambda x: x ** 0.43
    >>> matrix_XYZ_to_LMS = np.array(
    ...     [[0.4002, 0.7075, -0.0807],
    ...      [-0.2280, 1.1500, 0.0612],
    ...      [0.0000, 0.0000, 0.9184]])
    >>> matrix_LMS_p_to_Iab = np.array(
    ...     [[0.4000, 0.4000, 0.2000],
    ...      [4.4550, -4.8510, 0.3960],
    ...      [0.8056, 0.3572, -1.1628]])
    >>> XYZ_to_Iab(
    ...     XYZ, LMS_to_LMS_p_callable, matrix_XYZ_to_LMS, matrix_LMS_p_to_Iab)

black could produce the following output:

    >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
    >>> LMS_to_LMS_p_callable = lambda x: x**0.43
    >>> matrix_XYZ_to_LMS = np.array(
    ...     [
    ...         [0.4002, 0.7075, -0.0807],
    ...         [-0.2280, 1.1500, 0.0612],
    ...         [0.0000, 0.0000, 0.9184],
    ...     ]
    ... )
    >>> matrix_LMS_p_to_Iab = np.array(
    ...     [
    ...         [0.4000, 0.4000, 0.2000],
    ...         [4.4550, -4.8510, 0.3960],
    ...         [0.8056, 0.3572, -1.1628],
    ...     ]
    ... )
    >>> XYZ_to_Iab(
    ...     XYZ, LMS_to_LMS_p_callable, matrix_XYZ_to_LMS, matrix_LMS_p_to_Iab
    ... )

Describe alternatives you've considered

I'm manually formatting the code.

Additional context

N/A

KelSolaar avatar May 22 '22 09:05 KelSolaar

Thank you for opening the discussion again. Personally, after #2150, #3087 and the like, I'm increasingly hesitant to push for more docstring changes. To be fair though, formatting docstrings could be less controversial than us choosing a strict docstring style. Since doctests are code, would this be more appropriate as a dedicated tool wrapping Black?

felix-hilden avatar Jun 26 '22 18:06 felix-hilden

Since doctests are code, would this be more appropriate as a dedicated tool wrapping Black?

This is a good point!

KelSolaar avatar Jun 30 '22 07:06 KelSolaar

Question: isn't this already supported by blacken-docs?

adam-grant-hendry avatar Jul 03 '22 22:07 adam-grant-hendry

Question: isn't this already supported by blacken-docs?

After posting this, I realized that extension only works on documentation files (.rst/.md/.tex), but not directly on python files.

adam-grant-hendry avatar Jul 03 '22 22:07 adam-grant-hendry

However, blackdoc works on python files. Depending on where you are placing doctests, you may need both packages.

adam-grant-hendry avatar Jul 03 '22 22:07 adam-grant-hendry

Oh awesome! I will give it a stab, that would be certainly worth showcasing in the black docs/website!

KelSolaar avatar Jul 04 '22 08:07 KelSolaar

I'd be willing to consider advertising some of these tools in, say, our "integrations"!

felix-hilden avatar Jul 04 '22 09:07 felix-hilden

Would like to work on this

rajveer43 avatar Sep 29 '23 11:09 rajveer43

Renamed the issue to reflect the discussion above: we won't do this in Black itself, but we should document third-party tools that can do this.

JelleZijlstra avatar Oct 10 '23 15:10 JelleZijlstra

However, blackdoc works on python files. Depending on where you are placing doctests, you may need both packages.

blacken-docs supports formatting code in doctests, as long as they are within Markdown/reStructuredText blocks in docstrings. For example (adapted from the project README):

def f():
    """docstring here

    ```pycon
    >>> print("hello world")
    ```
    """

or

def f():
    """docstring here

    .. code-block:: pycon

        >>> print("hello world")
    """

However, it doesn't support doctests that aren't in Markdown/reStructuredText blocks (issue is old, but I'm pretty sure it hasn't changed).

blackdoc does support them, but it's not actively maintained.

The issue with using both packages is that they don't fully agree:

class _UDF:
    ...
    
    @util.experimental
    @classmethod
    def python(cls, fn=None, *, name=None, schema=None, signature=None, **kwargs):
        """
        Examples
        --------
        ```pycon
        >>> import ibis
        >>> @ibis.udf.scalar.pandas
        ... def add_one(x: int) -> int:
        ...     return x + 1
        >>> expr = add_one(2)
        >>> con = ibis.connect(os.environ["SNOWFLAKE_URL"])  # doctest: +SKIP
        >>> con.execute(expr)  # doctest: +SKIP
        3
        ```
        """

The above is formatted by blackdoc. If you use blacken-docs (given the doctest is in a pycon block), you get an extra ... after the ... return x + 1 line.

edit: Another example... if you have a docstring using single quotes, blackdoc isn't properly formatting that in doctest, either...

edit2: On the flip side, blacken-docs seems to ignore pycon doctest blocks further down in the same file, weird; will try to create an issue on their repo. In any case, my overall point is that it's hard to make an (official?) recommendation if the tools aren't working consistently.

deepyaman avatar Oct 31 '23 13:10 deepyaman

I would Like you work on this issue .

toshiksharma271 avatar Dec 18 '23 17:12 toshiksharma271