Move Matplotlib backend mapping to Matplotlib (#14371)...
Move Matplotlib backend mapping to Matplotlib (#14371)
This is WIP to move IPython's backend mapping into Matplotlib and
extends it to allow backends to register themselves via [entry
points](
https://setuptools.pypa.io/en/latest/userguide/entry_point.html#entry-points-for-plugins).
It is a coordinated effort across Matplotlib, IPython, matplotlib-inline
and ipympl. Closes
#14311. Most of the work is in Matplotlib
(matplotlib/matplotlib#27948) but I will repeat the relevant points
here.
When using a Matplotlib magic command of the form `%matplotlib
something` the identification of the Matplotlib backend and GUI loop are
now performed in Matplotlib not IPython. This supports:
1. Matplotlib backends that IPython already supports such as `qtagg` and
`tkagg`.
2. Other built-in Matplotlib backends such as `qtcairo`.
3. Backends that use `module://something` syntax such as
`module://mplcairo.qt`.
4. Backends that self-register using entry points, currently `inline`
and `widget`/`ipympl`.
Implementation details:
1. The magic command is now explicitly `%matplotlib gui_or_backend`
rather than `%matplotlib gui`. This is already effectively the case as
e.g. `%matplotlib ipympl` is really a backend not GUI name. Within
Matplotlib the `gui_or_backend` is checked first to see if it is a GUI
name and then falls back to checking if it is a backend name.
2. If you select the `inline` backend the corresponding GUI is now
`None` not `inline`. All backends which do not have a GUI loop return
`None`, otherwise we have to keep explicit checks within IPython for
particular backends.
3. `backends` and `backend2gui` are now deprecated but are still
exposed, with a deprecation warning, if required. If using Matplotlib,
ipympl, etc releases that include the corresponding changes to this PR
then they are not needed as Matplotlib deals with it all. But for
backward compatibility they must still be available for a while along
with the remainder of the existing backend-handling code.
4. I haven't yet updated the documentation but we need to keep
information about valid GUI frameworks and I propose that we should
remove all lists of valid Matplotlib backends, replacing them with
instructions on how to obtain the current list (pointing to the
Matplotlib docs and using `%matplotlib --list`). If we keep any lists
then they will inevitably become out of date. This extends to the
`backend_keys` in IPython/core/shellapp.py.
Because the four related projects are loosely coupled without direct
dependencies on each other (except for `ipython` and
`matplotlib-inline`), backward compatibility requires all possible
combinations of projects before and after the new functionality (I will
call these "old" and "new" from now on) to continue to work. I have
tested these all locally, and the CI of this PR will test new IPython
against old Matplotlib for example, but I need to add one or more new
temporary CI runs to test new IPython against new Matplotlib etc. The
identification of new versus old depends on version checks on the other
libraries, so here is a table that I will update showing the current
status of progress in the 4 projects:
| Project | Relevant PRs | Possible release version |
| --- | --- | --- |
| matplotlib-inline | ipython/matplotlib-inline#34,
ipython/matplotlib-inline#35 | 0.1.7 |
| ipympl | matplotlib/ipympl#549 | 0.9.4 |
| Matplotlib | matplotlib/matplotlib#27948 | 3.9.1 |
| IPython |
#14371 (this) | 8.24.0 |
The two widget projects can be released soon, once we are happy with the
entry point approach. The other two projects' PRs will have to be
synchronised as each includes version checks on each other.
To do
- [ ] Add CI runs against the new PR branches of the other projects.
- [ ] Add comments for conditions required for backward-compatibility
code blocks to be removed.
- [ ] Update documentation, including removal of lists of valid
backends.
- [ ] Update version checks before merging.