-
-
Notifications
You must be signed in to change notification settings - Fork 509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Doctest framework fails to parse multiline input pasted from sage interactive prompt #10458
Comments
Attachment: test.rst.gz testing docstring |
comment:1
The Sage command line interface uses IPython, which is responsible for printing line continuation of the form "...:". It could be more appropriate to fix this issue upstream in the IPython project. We could send a patch upstream or find out how to get IPython to do line continuation of the form "...". |
patch to make sage recognize "....:" continuation line prefixes in doctests |
comment:2
Attachment: continuation.patch.gz Well, Sage already replaces "sage:" with ">>>", so why not replace "....:" with "..."? In any case, "....:" looks better, since it is the same length as "sage:", making the line prefix look more like a separate "column", as it should (note that it is "....:" with four periods, not "...:" as you have written). Here is a patch which seems to work (at least the attached test.rst passes). What do you think? I'm currently running I'm new to sage_trac, so forgive me if setting my username as the "Author" was not the correct thing to do. |
Author: kini |
comment:3
OK, that didn't take all that long. All tests pass. |
This comment has been minimized.
This comment has been minimized.
comment:4
This is really a major change to how the doctesting framework behaves. The issue needs to be raised on sage-devel for some discussion. |
This comment has been minimized.
This comment has been minimized.
comment:5
Just fixed the And the Author(s) field. (This should contain the real name(s).) |
Changed author from kini to Keshav Kini |
comment:6
On topic: I would consistently add the trailing blank in the prompt substitutions. At first glance it seems we currently lose the original (non-preparsed) source code of continuation lines (but also that this isn't a regression). |
comment:7
I'm not sure what you mean by "consistently add the trailing blank". The substitutions I patched in do not remove or add any further spaces, so no loss of trailing blanks will occur. If there was a blank after a "...", "....:", or "sage:", there will correspondingly be one after the "...", "...", or ">>>" respectively. Yeah, I'm not too sure why the source code disappears from all but the first line. |
comment:8
Replying to @kini:
I mean add the space to all prompt patterns to match (and of course their substitutes), e.g. line 485 (it's in the comment, but not the code) and line 613 (also in the comment on line 251). |
comment:9
P.S.: The patch lacks a ticket number in the commit message. We have the convention to prepend (e.g.) |
comment:10
Replying to @nexttime:
Ah, I see. Yes, I left those alone because changing them would change the behavior of the doctesting framework for docstrings containing lines like "sage:dostuff()" or "...dostuff()". Arguably the doctest framework shouldn't be allowing lines like that anyway, but at the moment it does... Replying to @nexttime:
OK, I'll fix the patch up then. By the way, when changing my patch submission should I be uploading further patch files to layer on top of the one I've got here, or replacing this patch with new patches which diff to 4.6? |
comment:11
Replying to @kini:
Well, that's just another bug (we should fix here, too).
Depends on the changes. Unfortunately, ordinary trac users cannot delete (or rename) attachments, not even their own. So you could upload a new patch with In general, it's ok to replace your patch with an updated one (sometimes better than having Also, patches should be based on the most recent developer version of Sage, i.e. the current alpha or rc. Unless there are merge conflicts (because someone else has changed code near to your changes), it's ok to have it based on some previous official release, too. (But you should always check your patch applies clean to the latest developer release.) The attachment comment should contain the name of the repository to which to apply the patch (the "default" is the Sage library), in this case "Scripts repo", and usually also mentions on what Sage release it is based, since it is not unusual new releases get out before a ticket gets merged. |
comment:12
Replying to @nexttime:
I've applied the following patch to (the vanilla) diff --git a/sage-doctest b/sage-doctest
--- a/sage-doctest
+++ b/sage-doctest
@@ -248,7 +248,7 @@
"""
Run the preparser on the documentation string s.
This *only* preparses the input lines, i.e., those
- that begin with "sage:".or with "..."
+ that begin with "sage: ".or with "... "
"""
sl = s.lower()
@@ -260,16 +260,16 @@
last_prompt_comment = ''
for L in s.splitlines():
- begin = L.lstrip()[:5]
+ begin = L.lstrip()[:6]
comment = ''
- if begin == 'sage:':
+ if begin == 'sage: ':
c, comment = comment_modifier(L)
last_prompt_comment = comment
line = ''
if LONG_TIME in c and not long_time:
L = '\n' # extra line so output ignored
if RANDOM in c:
- L = L.replace('sage:', 'sage: print "ignore this"; ')
+ L = L.replace('sage: ', 'sage: print "ignore this"; ')
if NOT_TESTED in c:
L = '\n' # not tested
if NOT_IMPLEMENTED in c:
@@ -287,10 +287,10 @@
line += '\n' + ' '*i + 'ignore ...\n'
t.append(line)
- elif begin.startswith('...'):
+ elif begin.startswith('... '):
comment = last_prompt_comment
i = L.find('.')
- t.append(L[:i+3] + sage.misc.preparser.preparse(L[i+3:]))
+ t.append(L[:i+4] + sage.misc.preparser.preparse(L[i+4:]))
else:
comment = last_prompt_comment
@@ -380,11 +380,11 @@
j = 0
while j < len(F):
L = F[j].rstrip()
- if L.lstrip()[:5] == 'sage:':
+ if L.lstrip()[:6] == 'sage: ':
while j < len(F) and L.endswith('\\') and not L.endswith('\\\\'):
j += 1
i += 1
- L = L[:-1] + F[j].lstrip().lstrip('...').rstrip()
+ L = L[:-1] + F[j].lstrip().lstrip('... ').rstrip()
L += '###_sage"line %s:_sage_ %s_sage"'%(i, L.strip())
j += 1
i += 1
@@ -478,8 +478,8 @@
return ''
s += test_code(os.path.abspath(file_name))
- # Allow for "sage:" instead of the traditional Python ">>>".
- s = s.replace("sage:",">>>").replace('_sage"','')
+ # Allow for "sage: " instead of the traditional Python ">>> ".
+ s = s.replace("sage: ",">>> ").replace('_sage"','')
return s
@@ -607,8 +607,8 @@
cnt += 1
if cnt > 1000:
break
- s = s.replace(':_sage_',':\n').replace('>>>','sage:')
- c = '###line [0-9]*\n'
+ s = s.replace(':_sage_',':\n').replace('>>> ','sage: ')
+ c = '###line [0-9]+\n'
r = re.compile(c)
s = r.sub('\n',s)
if cnt > 0: (Note that there are more occurrences than I had found in your patch / mentioned above.) So I would suggest to [re]base your enhancement (accepting " After that we could address the "lost original source code of continuation lines" issue, with another patch, perhaps on a follow-up ticket if you like. |
comment:13
P.S.: We already had trouble with lines starting with " |
comment:14
ping |
comment:15
I've added this ticket to the !leet meta-ticket for doctesting issues, #11337. :) |
comment:16
Another, slightly related issue is that you can't simply copy tracebacks from the But we could document (in the Developer's Guide) that one has to strip the exception type, i.e. anything up to |
comment:17
Replying to @nexttime:
And someplace the first line of a traceback lacks a colon, and a doctest needs one. And maybe in the notebook it is different yet again? Or something like that. See semi-related, new ticket #11621. Does it belong in the meta-ticket? I tripped over it as part of doctesting Sage examples placed into a textbook where I need to be careful about long lines for the printed version. |
comment:18
Replying to @rbeezer:
As it only deals with the preparser and not the doctesting framework, I don't think so.
Release date / deadline? ;-) |
comment:19
Replying to @nexttime:
Open source. So, no deadline. Release date: maybe within the week. Watch sage-edu/sage-devel. I solved my immediate problem by breaking the input into pieces. Not as pretty as it could be, but not bad either. Rob |
comment:20
I think this is fixed by #12415. |
Reviewer: Keshav Kini |
Changed author from Keshav Kini to none |
comment:22
Awesome! :) A bit sad that the first patch I ever wrote for Sage is going to be thrown away, but it was a mere bandaid compared to #12415's cyborgization :P |
See this sage-devel thread for some discussion about the changes proposed by this ticket.
After some confusion trying to get a docstring to pass doctesting, I think input line continuations are "not working", in that lines directly pasted from the sage interpreter prompt do not pass doctests when single inputs span multiple lines. Pasted below is some terminal output (analysis continued afterwards):
After I replace all "....: " with "... " using
sed
, everything seems to work fine.It seems to me that the problem is that sage is not converting "....: " to "... ", which is what the standard python interactive prompt uses as a prefix for continued input lines. However, the sage prompt uses "....: ", so IMHO the doctesting framework should allow for this, so that lines from sage sessions can really be just dumped into a docstring without any further editing.
Component: doctest coverage
Keywords: continuation, multiline input, interactive prompt
Reviewer: Keshav Kini
Issue created by migration from https://trac.sagemath.org/ticket/10458
The text was updated successfully, but these errors were encountered: