Skip to content
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

[MRG] Fix "invalid cursor position" error #145

Merged
merged 1 commit into from
Nov 13, 2016

Conversation

wmvanvliet
Copy link
Contributor

@wmvanvliet wmvanvliet commented Oct 7, 2016

Since the QTextEdit object that we use as main text widget has the maximumBlockCount constraint set, lines of text can get removed from the beginning of the document at any time text is append to the document.

This PR fixes a particularly nasty bug where self._append_before_prompt_pos is incorrectly computed, leading to the QTextCursor::setPosition: Position '14083' out of range error.

It is important to keep proper track of the beginning and end position of the prompt, also when text is inserted or removed. Instead of manually tracking this position by computing offsets when doing text operations, this PR uses QTextCursor objects to do this.

Fixes #76, #94, #107

@wmvanvliet
Copy link
Contributor Author

To clarify: the error occurs because first, self.append_before_prompt_pos is computed, then the prompt is appended to the document, causing the first line of the document to be removed, causing the just computed position to be wrong.

@takluyver
Copy link
Member

This sounds sensible. Heads up, though, that the Qt console is mostly community maintained these days, because the core team don't use it very often and aren't especially familiar with Qt.

@ccordoba12 do you want to have a look at this?

@wmvanvliet
Copy link
Contributor Author

@takluyver Who do I talk to, to become a maintainer for this project? I use it every day.

@takluyver
Copy link
Member

I was hoping you might say that. ;-) Make a few PRs like this; I'd like to give Carlos the opportunity to review them (he also has an interest in the Qt console, particularly for use in Spyder), and if all goes well we'll make you a maintainer.

@ccordoba12
Copy link
Collaborator

Will do this weekend, thanks for pinging me :-)

@wmvanvliet wmvanvliet changed the title Fix "invalid cursor position" error [WIP] Fix "invalid cursor position" error Oct 13, 2016
@wmvanvliet
Copy link
Contributor Author

@ccordoba12 somehow the stuff from #141 has gotten mixed up in this PR as well and I can't seem to untangle it right now. But otherwise this PR is ready for a review. This should squash the annoying "invalid cursor position" errors once and for all. Furthermore, this should prevent the console from ever "locking up".

@wmvanvliet wmvanvliet changed the title [WIP] Fix "invalid cursor position" error [MRG] Fix "invalid cursor position" error Oct 13, 2016
"""Find the position in the text right after the prompt"""
return min(self._prompt_cursor.position() + 1, self._get_end_pos())

_prompt_pos = property(_get_prompt_pos)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't this be written as

@property
def _prompt_pos(self):
    return self._get_prompt_pos()

?

I think it'd be clearer :-)

return min(self._append_before_prompt_cursor.position(),
self._get_end_pos())

_append_before_prompt_pos = property(_get_append_before_prompt_pos)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this as

@property
def _append_before_prompt_pos(self):
    return self._get_append_before_prompt_pos()

?

elif status == 'aborted':
self._process_execute_abort(msg)
# If status == 'error', a message of type 'error' will be sent with
# the details
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment necessary? I don't think so :-)

@@ -661,7 +666,7 @@ def reset(self, clear=False):

# update output marker for stdout/stderr, so that startup
# messages appear after banner:
self._append_before_prompt_pos = self._get_cursor().position()
#self._append_before_prompt_pos = self._get_cursor().position()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this comment be removed?

if content['ename'] == 'KeyboardInterrupt':
# If the user interrupted execution by pressing CTRL-C, only
# display a simple message.
self._append_plain_text("Execution aborted\n")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this idea a lot. It'd prevent displaying long tracebacks that don't mean much to the user.

@takluyver, what do you think about it?

@ccordoba12 ccordoba12 added this to the 4.3 milestone Oct 13, 2016
@ccordoba12
Copy link
Collaborator

I did a quick review for now. I still have to take a look at the logic :-)

@ccordoba12
Copy link
Collaborator

@wmvanvliet, does this close a particular issue? If so, please mention it in the PR description as Fixes #foo

@wmvanvliet wmvanvliet force-pushed the truncating_fix branch 2 times, most recently from c6be6da to d0f8c3c Compare October 17, 2016 10:12
@wmvanvliet
Copy link
Contributor Author

Rebased this to be a clean PR (no more code from others PR's sneaking their way into this one).

@ccordoba12 Comments addressed, thanks for the review!

@@ -1653,7 +1646,7 @@ def _get_last_lines(self, text, num_lines, return_count=False):
break
i += 1
if return_count:
return text[pos:], i
return text[pos:], i + 1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this + 1 here?

@ccordoba12
Copy link
Collaborator

I added one minor comment, just for my own enlightenment :-) Otherwise, this looks good to me.

@wmvanvliet, thanks a lot for working on a fix for this nasty bug. It's really appreciated!

@takluyver
Copy link
Member

Yeah, I forgot to say thanks!
This has been a niggly recurring issue that we thought we'd fixed a couple of times, it's great to have what sounds like a proper robust fix for it.

Since the QTextEdit object has a maximumBlockCount constraint, lines of
text can get removed from the beginning of the document at any time we
append to the document.

It is important to keep proper track of the beginning and end position
of the prompt, also when text is inserted or removed. Instead of
manaully tracking this position by computing offsets when doing text
operations, this commit uses QTextCursor objects to do this.

This commit fixes a bug where self._append_before_prompt_pos is
incorrectly computed, due to text being removed as the prompt is being
appended to the document.

fixes jupyter#94, jupyter#107
@wmvanvliet
Copy link
Contributor Author

There were some erratic changes in this PR due to the mess I'd made of my Git branch. I think I've got it sorted out now. Thanks for catching that @ccordoba12.

@ccordoba12
Copy link
Collaborator

Thanks @wmvanvliet! Merging now :-)

@ccordoba12 ccordoba12 merged commit f3f96b6 into jupyter:master Nov 13, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

After a kernel reset, input line hangs
3 participants