| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
IPython can also be used to simply run files; when this is the case we
are not going to be interactive; and we do not want to enable the
eventloop integration. Otherwise someone doing:
$ ipython script.py
Will simply see a window blink, as IPython will exit immediately instead
of showing the window and exit.
I'm not quite sure how to test that are we basically _want_ something to
block forever and wait for user input; so no test added
Closes: ipython/ipython#11837
|
This is also related to #14950 so may not be a proper fix. |
Sorry, something went wrong.
| try: | ||
| mpl.rcParamsOrig["backend"] = mpl.rcParams["backend"] | ||
| ip.enable_matplotlib() | ||
| if is_non_interactive_terminal_ipython(ip): |
There was a problem hiding this comment.
Can you 1) make the function private (leading underscore) and 2) perhaps move the check a bit earlier, e.g. in line 1649 if not ip or _is_non_interactive...(ip)?
Sorry, something went wrong.
|
thanks! just a minor nitpick. |
Sorry, something went wrong.
| return figure._cachedRenderer | ||
|
|
||
|
|
||
| def is_non_interactive_terminal_ipython(ip): |
There was a problem hiding this comment.
This does only check attributes of ip, so I feel it should belong to the IPython object and should be implemented there as IPython.is_interactive or similar.
Then one can do:
if ip.is_interactive:
ip.enable_matplotlib()
Or maybe even in enable_matplotlib()
def enable_matplotlib(self):
if not self.is_interactive:
warnings.warn('enable_matplotlib() called on a non-interactive IPython.'
'Matplotlib interactive mode is not enabled.'
'This will raise a RuntimeError in furture versions.')
return
...
Sorry, something went wrong.
There was a problem hiding this comment.
But then we would only support versions of ipython>=whatever-implements-this.
Sorry, something went wrong.
There was a problem hiding this comment.
Which is the reason I did it this way, and also ip.is_interactive make no-sens on non-TerminalInteractiveShell. When running matplotlib in notebook, you will get a different type for ip (ZmqInteractiveShell). And both are subclass of a base class which can be overridden by other implementations.
To be clearer this function test:
Sorry, something went wrong.
There was a problem hiding this comment.
I'm ok with the present approach for back-comatibility.
Sorry, something went wrong.
|
Can we just revert the commit that introduced the problem and then rethink this from scratch? I feel like matplotlib should provide the interface and attributes, such that IPython can query all the information it needs to decide what to do; not matplotlib deciding what IPython should do. |
Sorry, something went wrong.
Sorry, something went wrong.
|
@ImportanceOfBeingErnest In principle you are correct but we are constrained by some history (as we want IPython and Matplotlib to both work with future / old versions of the other) and the conflict between user expectations and lazyness. On one hand users want to be able to just import plt and have it "do the right thing" of setting up the input hooks, but when IPython starts we don't know if Matplotlib is going to be used (so we do not want to pre-emptively import Matplotlib and even if we did preemptively import Matplotlib, we don't know which GUI framework the user is going to want so use. Thus, Matplotlib has to tell IPython, as late as possible, "ok now set up the input hook" as that is when we are truely locked into a given backend. In the past people have had to remember to type %matplotlib to manually enable the connection, but as of 1.5.3 (#6734) we will at pyplot import time poke IPython to set things up, however this does not work for backends that IPyhon does not know about which is what this code is supposed to fix. The second to last commit changes to using the gentler ip.enable_gui. The last commit simplifies it further and avoids monkey-patching IPython all together. |
Sorry, something went wrong.
|
Note that the above approach does not preclude to improve and expose more things in IPython; and we also likely want at some point to clear all the old code path. Matplotlib master is still amazingly workswith IPython 3.0 (released in 2015). I'm open to remove old compat layer though – maybe we should more carefully comment whcih code path are for older version of IPython :-) |
Sorry, something went wrong.
|
IIUC you want that people can get cairo plots in IPython by just updating matplotlib, without updating IPython? Isn't that a very special case? Like, if I know I need to update matplotlib anyways, I could just update IPython as well. |
Sorry, something went wrong.
Maybe you can but not everyboy can; but you can't assume that everyboy will think about this, take the time to do it or has the possibility to do it. IPython also oes have bugs, and we regularly have people that have to get to olde IPython version for some other unrelated bugs. And if you start this way, why not be always up to date will al the libraries ? Why isn't everyone using Python 3.8 two days after it is out ? This also mean that first we need to get the update in IPython; then release IPython, then release matplotlib. That also does not help with downstream packagers in Debian and Co. who now may also have to package IPython first. Packages that works with each other have to work with previous/next versions if you want to have any chance to a be a bit friendly with users. |
Sorry, something went wrong.
|
This will also be an issues with ipympl. |
Sorry, something went wrong.
|
I really feel I'm missing something here. So all of this is just for the one person on earth who wants to use a non-standard backend and cannot type plt.switch_backend("Qt5Cairo") or whatever they need into the console? |
Sorry, something went wrong.
|
What ipython needs to do is basically read the required_interactive_framework attribute (which is new in mpl3.0 and which I'm proposing, in #14521, to move to somewhere slightly more practical for third-party backend developers (basically they can mostly just ignore it if that PR gets merged)) and enable the correct event loop based on that. Note that this is not only for qt5cairo, but also for mplcairo and any other backend that may exist out there (of which there may admittedly not be that many). @ImportanceOfBeingErnest to be honest, it is not clear to me why you think this patch would better live in IPython's codebase rather than in Matplotlib's. For example, if #14521 goes in, IPython would need to carry more or less forever code to handle either location of required_interactive_framework, whereas by having the patch on Matplotlib's side, we can immediately update the IPython integration to use the new location. Also, the complexity of the patch is bascailly the same wherever it lives. |
Sorry, something went wrong.
|
plt.switch_backend("Qt5Cairo") does not bind the GUI event loop until the first figure is created (so that you can have one GUI in your rc params, but still switch after pyplot is imported and before the first figure is created. This is extremely useful for users who may import things that in turn import pyplot so they do not have to be super careful about import order (and was a very long standing complaint). Hopefully mplcairo will grow a decent user base and, as I said above, I suspect that this will also be useful for ipympl. |
Sorry, something went wrong.
Hey, it's not because we have asingle bug report that there is a single person that have the issue. And note the reporter in the IPython issue never said they they couldn't type plt.switch_backend("Qt5Cairo"); they were concerned about teaching python/ipython and matplotlib and reported a difference of behavior between Python and IPython. And it appear that the same piece of code also trigger issues with users that use plt.ioff(); so it definitively look like there is an issue in the logic. Also sie note; I'm not a maintainer here and only swing by every now and then, but I'm not quite sure if I need to interprete your comments as a real genuine desire to understand, or a lack of empathy toward other user's needs. I have usually a tough skin and had to fight a lot with the language and cultural barrier when trying to express myself in international projects, but the way you present things can be extremely offputting to anyone reading this thread. New users may not distinguish a contributor from a maintainer; which can make feel like the project just does not care about their use case. Keep in mind that for every people commenting on a thread there might be dozens just lurking. |
Sorry, something went wrong.
|
I am extremely concerned about user's needs. And one of the highest goods is hence the stability of the code-base, i.e. not to break people's code from one version to the next. |
Sorry, something went wrong.
I don't disagree that we need stability; but whether or not we had release this in 3.1 or 4.0 it would have been broken; none of us design code to have bugs. Without the experience of this breakage; we would likely had never find this corner case anyway. And we are not going from one makeshift solution to another; we explore what is possible doing what we can; and cleaning up when possible to get better solutions. Remove the change is also a problem for the same stability reason you give us; if we remove it then user relying on some of those behavior in 3.1 would lose it in 3.2. That's not good either. In the end it's always a question a trade off; maybe reverting will be the solution, but maybe it's not. One thing for sure this is a relatively hard problem, and without experiments we won't get all things right. No plan survives contact with the enemy, and enemy is the rest of the folks that don't work on master. As usual there is an XKCD for this https://xkcd.com/1172/ |
Sorry, something went wrong.
|
I think this should be merged as-is and I will follow up with a PR that removes the enable_gui logic from pyplot and moves it all to the backend. This will let us not try to install the input hook until we actually need it (which is the first time the user creates the canvas which is when we are really locked to one GUI framework). |
Sorry, something went wrong.
|
Let's give a few days to @ImportanceOfBeingErnest to reply, unless you want to push 3.1.2 out tomorrow... |
Sorry, something went wrong.
|
Oh, I don't think I have anything more to add here. I've made the problem clear. And it seems it's being understood. |
Sorry, something went wrong.
|
ok, let's try this, then :) |
Sorry, something went wrong.
|
Owee, I'm MrMeeseeks, Look at me. There seem to be a conflict, please backport manually. Here are approximate instructions:
$ git checkout v3.1.x $ git pull
$ git cherry-pick -m1 bd98f12d76433dd67c12504a43553ba6e2bf02d5
$ git commit -am "Backport PR #14979: FIX: Don't enable IPython integration if not entering REPL."
git push YOURFORK v3.1.x:auto-backport-of-pr-14979-on-v3.1.x
And apply the correct labels and milestones. Congratulation you did some good work ! Hopefully your backport PR will be tested by the continuous integration and merged soon! If these instruction are inaccurate, feel free to suggest an improvement. |
Sorry, something went wrong.
…f not entering REPL. FIX: Don't enable IPython integration if not entering REPL. (matplotlib#14979) FIX: Don't enable IPython integration if not entering REPL.
…-v3.1.x Backport PR #14979: FIX: Don't enable IPython integration if not ente…
| Back | FazBrowse Home | New Git URL |
IPython can also be used to simply run files; when this is the case we
are not going to be interactive; and we do not want to enable the
eventloop integration. Otherwise someone doing:
Will simply see a window blink, as IPython will exit immediately instead
of showing the window and exit.
I'm not quite sure how to test that are we basically want something to
block forever and wait for user input; so no test added
Closes: ipython/ipython#11837
PR Summary
PR Checklist