homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: DocTest and dict sort.
Type: behavior Stage:
Components: Extension Modules Versions: Python 2.5
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: endolith, jedie, rhettinger, tarek, tim.peters
Priority: normal Keywords:

Created on 2008年07月10日 13:59 by jedie, last changed 2022年04月11日 14:56 by admin. This issue is now closed.

Messages (7)
msg69501 - (view) Author: Jens Diemer (jedie) Date: 2008年07月10日 13:59
The doctest doesn't work good, if a function returns a dict.
Here a simple example:
def test(d):
 """
 This works:
 >>> test({"A":1, "B":2, "C":3})
 {'A': 1, 'C': 3, 'B': 2}
 
 This failed, because of different dict sort:
 >>> test({"A":1, "B":2, "C":3})
 {'A': 1, 'B': 2, 'C': 3}
 
 The Error messages:
 Failed example:
 test({"A":1, "B":2, "C":3})
 Expected:
 {'A': 1, 'B': 2, 'C': 3}
 Got:
 {'A': 1, 'C': 3, 'B': 2}
 """
 return d
The problem is IMHO that doctest.py [1] OutputChecker.check_output()
does compare the repr() of the dict and not the real dict as data.
One solution: Use eval() to convert the string repr. of the dict into
the real dict:
...
 #-----<add>-----
 try:
 if eval(got) == eval(want):
 return True
 except:
 pass #*pfeif* kein schoener stil, aber pragmatisch
 #-----</add>----
 # We didn't find any match; return false.
 return False
German discuss can be found here:
http://www.python-forum.de/topic-15321.html
[1] http://svn.python.org/view/python/trunk/Lib/doctest.py?view=markup 
msg69503 - (view) Author: Tarek Ziadé (tarek) * (Python committer) Date: 2008年07月10日 14:06
This is not a bug: dict do not guarantee the ordering of the keys, so it
may change on every run.
A good practice is to test a sorted .items() output of your dict in your
doctest.
msg69504 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2008年07月10日 14:13
Closing as not a bug.
FWIW, here's the relevant text from the docs:
---------------------------------------------
23.2.3.6 Warnings 
doctest is serious about requiring exact matches in expected output. If 
even a single character doesn't match, the test fails. This will 
probably surprise you a few times, as you learn exactly what Python 
does and doesn't guarantee about output. For example, when printing a 
dict, Python doesn't guarantee that the key-value pairs will be printed 
in any particular order, so a test like 
>>> foo()
{"Hermione": "hippogryph", "Harry": "broomstick"}
is vulnerable! One workaround is to do 
>>> foo() == {"Hermione": "hippogryph", "Harry": "broomstick"}
True
instead. Another is to do 
>>> d = foo().items()
>>> d.sort()
>>> d
[('Harry', 'broomstick'), ('Hermione', 'hippogryph')]
msg226006 - (view) Author: (endolith) Date: 2014年08月27日 23:39
I ran into this bug with sets, too. 
Expected:
 {6, 5, 3}
Got:
 set([5, 3, 6])
Documentation should illustrate how the function is actually meant to be used, not contrived examples that convert to sorted output purely so that doctest can understand them. doctest should be changed (or have an option) to understand object equality rather than exact text output.
msg226010 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2014年08月28日 04:44
> doctest should be changed (or have an option) to understand 
> object equality rather than exact text output.
Sorry, but that would be at odds with the fundamental design of doctest which is principally designed to test documentation in the form of docstrings (which, it goes without saying actually *are* strings).
Try using another tool for the job. The unittest module is well suited for tests that need to understand object equality.
msg226115 - (view) Author: (endolith) Date: 2014年08月30日 03:20
The fundamental purpose of doctest is to test that examples in documentation work correctly:
> To check that a module’s docstrings are up-to-date by verifying that all interactive examples still work as documented.
> To perform regression testing by verifying that interactive examples from a test file or a test object work as expected.
> To write tutorial documentation for a package, liberally illustrated with input-output examples. Depending on whether the examples or the expository text are emphasized, this has the flavor of "literate testing" or "executable documentation".
https://docs.python.org/2/library/doctest.html
(and this is not at all the purpose of the unittest module)
If a function returns a set, and the normal way to use it is to call the function and get a set, then the example should be to call the function and get a set:
>>> function()
set([1, 2, 3])
Doctest should therefore be able to test that the example actually works and returns the correct set, regardless of how the set elements are displayed. It should not be required to add unusual extra code to format the output specifically so that doctest can understand it:
>>> function() == set([1, 2, 3])
True
(This is not a realistic example, because the user wouldn't know what the output is until they call the function.)
>>> sorted(function())
[1, 2, 3]
(This is not how the method is actually used in reality. It returns a set for a reason, not a list.)
msg226117 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2014年08月30日 03:50
This should remain closed. It's "a feature" that doctest demands exact textual equality, and that the only way to override this is with one of the `#doctest:` flags. "What you see is what you get - exactly" is one of doctest's fundamental design goals.
If you would like to open a different report, suggesting (e.g.) a new "#doctest: object_equality" flag, go ahead. But I don't expect that would get a warm reception: there are many ways to write doctests with sets and dicts that already work fine. That you may have to add additional functions to make them pass in all cases isn't a bug: it's being explicit about that the raw unprocessed output is _not_ reliable.
If you don't want that level of pickiness, fine, use something else :-)
History
Date User Action Args
2022年04月11日 14:56:36adminsetgithub: 47582
2014年08月30日 03:50:36tim.peterssetnosy: + tim.peters
messages: + msg226117
2014年08月30日 03:20:26endolithsetmessages: + msg226115
2014年08月28日 04:44:36rhettingersetmessages: + msg226010
2014年08月27日 23:39:26endolithsetnosy: + endolith
messages: + msg226006
2008年07月10日 14:13:35rhettingersetstatus: open -> closed
resolution: not a bug
messages: + msg69504
nosy: + rhettinger
2008年07月10日 14:06:09tareksetnosy: + tarek
messages: + msg69503
2008年07月10日 13:59:53jediecreate

AltStyle によって変換されたページ (->オリジナル) /