classification
Title: Allow doctest to find line number of __test__ strings if formatted as a triple quoted string.
Type: behavior Stage: test needed
Components: Versions: Python 3.8, Python 3.7, Python 3.6, Python 3.5, Python 3.4
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: CuriousLearner Nosy List: CuriousLearner, jayvdb, jneb, r.david.murray
Priority: normal Keywords: easy, patch

Created on 2015-08-24 16:20 by r.david.murray, last changed 2018-11-26 20:25 by r.david.murray.

Files
File name Uploaded Description Edit
doctest_find__test__.patch r.david.murray, 2015-08-24 16:26 review
doctestfix.py jneb, 2018-03-13 14:52 Simple addition for doctest
Messages (8)
msg249060 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-08-24 16:20
Attached is a patch that enhances doctest discovery so that it can correctly report the line number for doctest errors in tests that are string values of the __test__ dictionary.  It only works if the strings are formatted as triple quoted strings, but since that is the most common case I think it is worth doing.

I don't have a test for this...I think it will require a unit test rather than adding to the doctests, since it needs to check the reported line number and other changes to test_doctest.py would change the line numbers.
msg253317 - (view) Author: Jurjen N.E. Bos (jneb) * Date: 2015-10-22 07:00
I am not as good in making nice patches, but that code can be improved upon a bit as follows:
<insert patch intro blurb here, same as original>

+        if isinstance(obj, str) and source_lines is not None:
+            # This will find __test__ string doctests if and only if the string
+            # contains any unique line.
+            for offset,line in enumerate(obj.splitlines(keepends=True):
+                if source_lines.count(line)==1:
+                    lineno = source_lines.index(line)-offset
+                    break

         # We couldn't find the line number.
         return None


I thing this will improve legibility and probably also speed under most circumstances.
msg253319 - (view) Author: Jurjen N.E. Bos (jneb) * Date: 2015-10-22 07:14
Oops. Lousy editing, I should have used return instead of break.

These 6 lines can be inserted in lib/doctest at line 1100:
+        if isinstance(obj, str) and source_lines is not None:
+            # This will find __test__ string doctests if and only if the string
+            # contains any unique line.
+            for offset,line in enumerate(obj.splitlines(keepends=True):
+                if source_lines.count(line)==1:
+                    return source_lines.index(line)-offset

And it works fine for me; the code is quite general and has predictable behaviour: any test string with a unique line in it will work.
msg313757 - (view) Author: Jurjen N.E. Bos (jneb) * Date: 2018-03-13 14:52
I always use the following piece of code that can be trivially used to patch the source.
It basically looks for a using line in the test string and finds it in the source file. If there is a match, we know where we are. Otherwise it falls back to the "normal" way.
msg313758 - (view) Author: Jurjen N.E. Bos (jneb) * Date: 2018-03-13 14:54
Oh wait, I already posted that so long ago I forgot about it.
Oops.
Sorry about the repetition, folks.
- Jurjen
msg314454 - (view) Author: Sanyam Khurana (CuriousLearner) * (Python triager) Date: 2018-03-26 14:56
Hey Jurjen,

Do you mind converting your patch in a Pull request please?
msg330253 - (view) Author: Sanyam Khurana (CuriousLearner) * (Python triager) Date: 2018-11-22 13:04
Hey  R. David Murray,

Where do you think the unit test for `doctest` should be placed? 

Should it be in `test_doctest.py`?
msg330460 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2018-11-26 20:25
Without looking at doctest.py, yes.  I believe the doctests in that file should be already plugged in to the unittest framework, so adding new testcase containing a non-doctest unit test should work fine.
History
Date User Action Args
2018-11-26 20:25:53r.david.murraysetmessages: + msg330460
2018-11-22 13:04:56CuriousLearnersetassignee: CuriousLearner
messages: + msg330253
versions: + Python 3.7, Python 3.8
2018-03-26 14:56:22CuriousLearnersetnosy: + CuriousLearner
messages: + msg314454
2018-03-13 14:54:03jnebsetmessages: + msg313758
2018-03-13 14:52:43jnebsetfiles: + doctestfix.py

messages: + msg313757
2015-11-04 03:02:29jayvdbsetnosy: + jayvdb
2015-10-22 07:14:47jnebsetmessages: + msg253319
2015-10-22 07:00:36jnebsetnosy: + jneb
messages: + msg253317
2015-08-24 16:26:01r.david.murraysetfiles: + doctest_find__test__.patch
2015-08-24 16:25:50r.david.murraysetfiles: - doctest_find__test__.patch
2015-08-24 16:20:04r.david.murraycreate