blackdoc
blackdoc copied to clipboard
`doctest` command continuation and chained methods
I'm having a problem with a doctest in one of my repos. We have some doctests where methods are chained, and they are written across multiple lines using the "command continuation" format. But I seem to have trouble getting both doctest
and blackdoc
to work simultaneously.
This example is trivial, but I think shows the problem:
def do_things():
"""
do things
Examples
--------
do this
>>> g=[8,2,3]
>>> sorted(g) \
.pop()
8
"""
pass
def do_things_differently():
"""
do things
Examples
--------
do this
>>> g=[8,2,3]
>>> sorted(g) \\
... .pop()
8
"""
pass
def do_other_things():
"""
do things
Examples
--------
do this
>>> g=[8,2,3]
>>> sorted(g) \
... .pop()
8
"""
pass
def do_that():
"""
do things
Examples
--------
do this
>>> g = [8, 2, 3]
>>> sorted(g)
.pop()
8
"""
pass
if __name__ == "__main__":
import doctest
doctest.testmod()
do_things
works as a doctest
, but it fails to parse in blackdoc
: error: cannot format /private/tmp/testing/test.py: Cannot parse: 12:0: EOF in multi-line statement
do_things_differently
also works as a doctest
, but fails to parse in blackdoc
: error: cannot format /private/tmp/testing/test.py: Cannot parse: 28:9: sorted(g) \\
do_other_things
parses in blackdoc
(and it suggests collapsing lines 44-45 into 1 line), but does not parse as a doctest
:
**********************************************************************
File "/private/tmp/testing/test.py", line 44, in __main__.do_other_things
Failed example:
sorted(g) ... .pop()
Exception raised:
Traceback (most recent call last):
File "/usr/local/Cellar/[email protected]/3.10.10_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/doctest.py", line 1350, in __run
exec(compile(example.source, filename, "single",
File "<doctest __main__.do_other_things[1]>", line 1
sorted(g) ... .pop()
^^^
SyntaxError: invalid syntax
**********************************************************************
do_that
parses correctly in blackdoc
, but gives the wrong answer in doctest
:
**********************************************************************
File "/private/tmp/testing/test.py", line 60, in __main__.do_that
Failed example:
sorted(g)
Expected:
.pop()
8
Got:
[2, 3, 8]
**********************************************************************
1 items had failures:
1 of 2 in __main__.do_that
***Test Failed*** 1 failures.
Obviously in this case we could just put everything on one line, but in general in our repo we'd to have it chained, on multiple lines. Is there a way to format this that I'm not seeing?
OS: MacOS 13.2.1 Python: 3.10.10 Blackdoc: 0.3.8
Thanks for your help.
The reason do_things
and do_things_differently
work with doctest
but not with blackdoc
is that doctest
executes the file, and python
will concatenate any lines with trailing \
with the following line. That's also why do_other_things
fail with doctest
: the concatenated lines contain the prompt.
blackdoc
does not know about \
(because I didn't teach it to), so any example that makes use of that will inevitably fail. I'm open to adding support for that since that's one of the things black
will reformat, but it seems a bit tricky to implement and I'm also unlikely to have time for that anytime soon.
For new code I'd use parens: they don't have the issues \
has, and it's also what black
will suggest using:
- >>> g=[8,2,3]
- >>> (sorted(g)
- ... .long_method_name1()
- ... .long_method_name2()
- ... .long_method_name3()
- ... .long_method_name4()
- ... .long_method_name5())
+ >>> g = [8, 2, 3]
+ >>> (
+ ... sorted(g)
+ ... .long_method_name1()
+ ... .long_method_name2()
+ ... .long_method_name3()
+ ... .long_method_name4()
+ ... .long_method_name5()
+ ... )
8
"""