Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

WebAgg backend: Fix unbound variable error in get_diff_image #8656

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

Merged
merged 2 commits into from
May 23, 2017
Merged

WebAgg backend: Fix unbound variable error in get_diff_image #8656

merged 2 commits into from
May 23, 2017

Conversation

cknd
Copy link
Contributor

@cknd cknd commented May 23, 2017

PR Summary

FigureCanvasWebAggCore.get_diff_image() can crash with an UnboundLocalError on its return value buff. This is because buff is only created when self._png_is_old == True, but get_diff_image tries to return it in either case.

We presumably ran into this because tornado likes to call FigureManagerWebAgg.refresh_all multiple times in between calls to draw() in certain situations -- then, even if draw() did set the _png_is_old flag, refresh_all resets it through its call to get_diff_image, and so the next refresh will fail.

This change keeps the buffer around as an attribute of the Canvas, so get_diff_image can return it regardless of whether it has been refreshed.

This change lets get_diff_image return None when the png isn't outdated and adds a condition to refresh_all to only send diffs that are non-None.


return buff
self.buff = buff
return self.buff
Copy link
Member

Choose a reason for hiding this comment

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

Would it be better to return buff inside the if block and return None if there is no changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

semantically yes, but the consumer of that return value in refresh_all then complains that None is not a buffer. (send_binary, that is)

    def refresh_all(self):
        if self.web_sockets:
            diff = self.canvas.get_diff_image()
            for s in self.web_sockets:
                s.send_binary(diff)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess refresh_all could inspect self.canvas._png_is_old to see whether there is a need to refresh, and otherwise just do nothing (no sending of binaries). but that's not entirely clean in terms of attribute access

Copy link
Member

Choose a reason for hiding this comment

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

Maybe in refresh_all it should only send the diff if it is non None? What does the consumer side do if it receives the same diff multiple times?

👎 on looking at private attributes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That sounds like the sanest way to do it. I've updated the PR

@tacaswell tacaswell added this to the 2.1 (next point release) milestone May 23, 2017
@QuLogic QuLogic merged commit 459f185 into matplotlib:master May 23, 2017
@cknd cknd deleted the feature_keep_buffer branch May 23, 2017 21:54
@cknd
Copy link
Contributor Author

cknd commented May 23, 2017

Thx for the quick reaction everyone!
I'm not familiar with the project's release schedule, but would it maybe make sense to include this already in the next bug fix release (2.0.3) instead of the 2.1 milestone?

@tacaswell
Copy link
Member

Congratulations on your first contribution to Matplotlib 🎉 ! Hopefully we will hear from you again.

It is unlikely that there will be a 2.0.3, but 2.1 is targeted for July.

@cknd
Copy link
Contributor Author

cknd commented May 24, 2017

Cheers for running a welcoming project! July-ish sounds perfectly reasonable for us. Thanks again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.