[Python-ideas] doctest

Devin Jeanpierre jeanpierreda at gmail.com
Fri Mar 2 14:05:05 CET 2012

On Fri, Mar 2, 2012 at 2:01 AM, Éric Araujo <merwok at netwok.org> wrote:
> Le 02/03/2012 07:55, Devin Jeanpierre a écrit :
>> [...] dicts and sets are not idiosyncratic or in any way
>> exceptional. doctest itself should handle them the way a naive user
>> would expect.
> This discussion seems to forget a core issue with doctest: The output
> lines can be *anything* that gets printed.  eval-able reprs of Python
> objects are only a part of the possibilities.  That’s why doctest cannot
> “just call sorted” on the output lines.

Ah, well, it sort of can. You can treat eval-able reprs of python
objects specially. But it gets messy. Simple treatments make the
treatment of e.g. dicts irreparably inconsistent. in doctest 2::

    This is totally fine
        >>> {-1:1, -2:1} # doctest: +LITERAL_EVAL
        {-1:1, -2:1}
    So is this (because doctest2 doesn't care that it was _printed_,
just that it was output):
        >>> print({-1:1, -2:1}) # doctest: +LITERAL_EVAL
        {-1:1, -2:1}
    This is not; don't do it bad dog bad bad bad dog (doctest2 has no
idea how to separate the repr from the printed text):
        >>> print(".", {-1:1, -2:1}) # doctest: +LITERAL_EVAL
        . {-1:1, -2:1}

I think maybe this behaviour is a little surprising, or at least a little dumb.

The solution I've had in mind is to only do object comparison if the
thing in the interpreter window is an expression, rather than a
statement. In such a scheme, only the first example would be safe. But
aside from not being a very useful distinction anyway, this doesn't
agree with the Python interpreter: displaying the last evaluated
expression even happens inside a statement. ">>> a;" is totally fine
and will display the repr of a. In fact:

    >>> for d in [{}, {-1:1}, {-2:1}, {-1:1, -2:1}]: d
    {-1: 1}
    {-2: 1}
    {-2: 1, -1: 1}

I can't really think of a way that makes sense and works everywhere,
except specifically marking up doctests with things like, "this is a
repr'd string; compare by object equality", and "this is a printed
string", and so on. That is no small change, but it's tempting. Of
course Sphinx would need to be able to turn this into a viewable
example. My only worry is that nobody would use it because it's dumb
or something, and it's hard to make it not dumb.

    >>> for d in [{}, {-1:1}, {-2:1}, {-1:1, -2:1}]: # doctest: +schematic
    ...     print("---"); d
        <eval>{-1: 1}</eval>
        <eval>{-2: 1}</eval>
        <eval>{-2: 1, -1: 1}</eval>

(Except seriously.)

-- Devin

More information about the Python-ideas mailing list