Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi version support for Python doctests

I am writing my doctests like this:

>>> some_function(a=1, b=2)
{u'id': u'123', u'name': u'abc'}

This works fine for Python version 2.5, 2.6 & 2.7 but fails for Python 3 with following error:

Expected:
    {u'id': u'123', u'name': u'abc'}
Got:
    {'id': '123', 'name': 'abc'}

Problem is that if I write my doctests like this:

>>> some_function(a=1, b=2)
{'id': '123', 'name': 'abc'}

They will work only for Python3 and fail on Python2 version. My question is how do I make it cross version compatible?

like image 329
Irfan Avatar asked Nov 20 '12 13:11

Irfan


People also ask

How do I run all Python Doctests?

Right click on a blank space in the python code, and there is a menu option to run all the Doctests found in the file, not just the tests for one function.

Does Pytest run Doctests?

By default, pytest will collect test*. txt files looking for doctest directives, but you can pass additional globs using the --doctest-glob option (multi-allowed).

What is the correct way to run all the Doctests in a given file from command line?

To run the tests, use doctest as the main program via the -m option to the interpreter. Usually no output is produced while the tests are running, so the example below includes the -v option to make the output more verbose.


2 Answers

I ran into the same problem with doctests in IPython. There's no neat solution, but I wrapped all of the u' prefixes in {}, i.e. {u}', and made a little function that would include or exclude them as appropriate.

You can see the u_format() function and a doctest using it.

But that's rather messy, so I've moved many tests away from doctests.

Alternatively, you can test it like this:

>>> some_function(a=1, b=2) == {'id': '123', 'name': 'abc'}
True

If you need some unicode strings in the keys, you can use u'abþ', and use distribute to run 2to3 on the doctests. But that only works on input code, not output reprs.

like image 165
Thomas K Avatar answered Oct 29 '22 13:10

Thomas K


I run into the same issue with doctests in NLTK; it was solved by using a custom doctest output checker (that treats u'foo' and 'foo' the same) which is installed by a custom nose plugin: https://github.com/nltk/nltk/blob/develop/nltk/test/doctest_nose_plugin.py

This solution is not pretty, but it works quite well (there are about 0.5 megabytes of doctests in NLTK) and it doesn't make doctests less readable.

EDIT: found a simplified standalone version of this nose plugin: https://github.com/gnublade/doctest-ignore-unicode

like image 36
Mikhail Korobov Avatar answered Oct 29 '22 14:10

Mikhail Korobov