-1

I am testing a function that produces results that are very long when represented, and I don't know how to fit that result into the doctest.

In this example, I'm using pscyopg2, which has verbose representations for its composed queries (details as to why)

from psycopg2.sql import Literal, Composed

def foo(a, b):
  """
  Examples:
    >>> foo('one', 'two')
    Composed([SQL('SELECT * FROM my_table WHERE a='), Literal('one'), SQL(' AND b='), Literal('two')])
  """

The result line can get really long, and I'm wondering if it's possible to break it up into multiple lines, like the input expression with ...

rovyko
  • 4,068
  • 5
  • 32
  • 44

2 Answers2

2

In this case you want to use the NORMALIZE_WHITESPACE flag:

def foo('one', 'two')
    """
    Examples:
        >>> foo('one', 'two')
        Composed([
           SQL('SELECT * FROM my_table WHERE a='), Literal('one'),
           SQL(' AND b='), Literal('two')
        ])
    """

if __name__ == '__main__':
    import doctest

    doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)
rovyko
  • 4,068
  • 5
  • 32
  • 44
  • `NORMALIZE_WHITESPACE` treats all sequences of whitespace (blanks and newlines) as equal. In your example you are introducing whitespace to places where it is not so the test will fail. For example between `Composed([` and `SQL` you cannot insert whitespaces in the doctest. – pabouk - Ukraine stay strong Jun 18 '23 at 23:02
2

Yes, you can use the NORMALIZE_WHITESPACE option for this.

From the documentation of the doctest module:

doctest.NORMALIZE_WHITESPACE

When specified, all sequences of whitespace (blanks and newlines) are treated as equal. Any sequence of whitespace within the expected output will match any sequence of whitespace within the actual output. By default, whitespace must match exactly. NORMALIZE_WHITESPACE is especially useful when a line of expected output is very long, and you want to wrap it across multiple lines in your source.

second emphasis mine

Either use this as an option to you command line when you run doctest:

python -m doctest -o NORMALIZE_WHITESPACE my_module.py

Or add an option directive to your code example:

def foo(a, b):
    """
    Examples:
       >>> foo('one', 'two') # doctest: +NORMALIZE_WHITESPACE
       Composed([SQL('SELECT * FROM my_table WHERE a='),
                 Literal('one'), SQL(' AND b='), Literal('two')])
    """
Community
  • 1
  • 1
silel
  • 567
  • 2
  • 10
  • The inline directive is what I was looking for! I knew I saw it before, but I couldn't find a code example in the documentation. Is it possible to write it above/below the `foo()` statement if it also needs to go over multiple lines? – rovyko Mar 13 '20 at 21:54
  • Just checked, you have to write it on the same "line" but it can go at the end of the last line. – rovyko Mar 13 '20 at 21:59
  • 1
    I'll take your word for it. The current version of the documentation on directives (python3.8 at the time of writing) is surprisingly sparse. About the "can it go above/below the `foo()` statetement?", I found the `doctest.set_unittest_reportflags()` function that might fit your need. Otherwise, pass the option to whatever you use to run doctest. Cheers! – silel Mar 13 '20 at 22:01