8000 Add BackendRegistry singleton class by ianthomas23 · Pull Request #27719 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Add BackendRegistry singleton class #27719

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 17 commits into from
Mar 9, 2024

Conversation

ianthomas23
Copy link
Member
@ianthomas23 ianthomas23 commented Jan 30, 2024

This is in preparation for #27663, moving the various hardcoded backend lists and dicts to a new BackendRegistry class that is intended to be the single source of truth for backends. There is no functional change.

There is a singleton backend_registry instance of the BackendRegistry class in registry.py. This is a similar implementation to that of the singleton rcParams instance of the RcParams class.

BackendRegistry includes the two public functions that are currently needed. There will eventually be a list_all function to list all backends including the built-in ones, those obtained via the "module://blah.blah" approach, and those registering themselves via entry points. The class internals will change too of course.

There are still some hardcoded backend names in _fix_ipython_backend2gui, but this will be addressed as part of the wider #27663 implementation.

I have not yet added an API change note. The backend_registry could be considered internal to Matplotlib except that IPython will also use it, so it could be thought of as fully public, or private with an exception for IPython. Other use of built-in backend lists by downstream libraries is probably restricted to use of rcsetup.interactive_bk, non_interactive_bk and all_backends. I have deprecated them in this PR to demonstrate that this is convoluted as they are module-level attributes that need to be deprecated using the recommendations of PEP 562. But probably I would be more inclined to keep them for the moment, until we are sure how this will all work in the end, and just pass through the backend_registry results.

(Edited to change name of singleton instance)

'pdf', 'pgf', 'ps', 'svg', 'template']
all_backends = interactive_bk + non_interactive_bk
# Deprecation of module-level attributes using PEP 562
_deprecated_interactive_bk = backendRegistry.list_builtin(BackendFilter.INTERACTIVE)
Copy link
Member Author

Choose a reason for hiding this comment

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

If we didn't deprecate these 3 attributes, this block of changes would be replaced by

interactive_bk = backendRegistry.list_builtin(BackendFilter.INTERACTIVE)
non_interactive_bk = backendRegistry.list_builtin(BackendFilter.NON_INTERACTIVE)
all_backends = backendRegistry.list_builtin()

Copy link
Member
@timhoffm timhoffm left a comment

Choose a reason for hiding this comment

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

Looks good to me.

anntzer
anntzer previously requested changes Feb 8, 2024
Copy link
Contributor
@anntzer anntzer left a comment

Choose a reason for hiding this comment

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

I'll block based on #27719 (comment) though only as a note that INTERACTIVE_NON_WEB should be removed; anyone can dismiss once fixed.

@ianthomas23 ianthomas23 force-pushed the backend_registry_enum branch from c9ca79f to ea74018 Compare February 9, 2024 11:16
@ianthomas23
Copy link
Member Author

I've removed all of INTERACTIVE_NON_WEB and put the special case for webagg/nbagg back in pyplot.py as requested by @anntzer. Also rebased to pick up other fixes so hopefully all CI will pass.

@anntzer anntzer dismissed their stale review February 12, 2024 16:30

handled



# Singleton
backend_registry = BackendRegistry()
Copy link
Member

Choose a reason for hiding this comment

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

Now we have matplotlib.backends.registry.backend_registry, which seems a bit redundant. Would it make sense to move this to _registry.py (to keep files small), and then import into matplotlib/backends/__init__.py so we have matplotlib.backends.registry as the instance?

Copy link
Member

Choose a reason for hiding this comment

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

I'd rather not. There is value in matching the the singleton instance name backend_registry to the class name BackendRegistry. Also the internal usage is from matplotlib.backends.registry import backend_registry, so the name is free standing. Only registry would be quite ambiguous (one could change to fully qualified usages only, but 🤷 ). And finally, the backend registry is used really rarely so that verbosity is not much of an issue.

Copy link
Member Author

Choose a reason for hiding this comment

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

I lean towards the explicit and verbose approach, but maybe there is some middle ground. If I keep the files named as they are but import into matplotlib.backends.__init__ using from .registry import BackendFilter, backend_registry then the standard usage becomes

from matplotlib.backends import backend_registry

rather than

from matplotlib.backends.registry import backend_registry

removing some verbosity.

This has the added advantage that you cannot import the BackendRegistry class in the same way which is good as nobody should need the class, only the singleton instance.

I have implemented this in commit 8f10a01.

@ianthomas23
Copy link
Member Author

I've also added docstrings, whats new and API changes information.

@tacaswell tacaswell added this to the v3.9.0 milestone Feb 14, 2024
@tacaswell
Copy link
Member

Were we also going to add a way for third-party backends to registering themselves?

@timhoffm
Copy link
Member

I very much think so. 😄 From the very top:

This is in preparation for #27663, ([MNT]: Move Matplotlib backend mapping from IPython and support backends self-registering)

@tacaswell
Copy link
Member

I very much think so. 😄 From the very top:

🐑 I failed my reading test for the day

@ianthomas23
Copy link
Member Author

I very much think so. 😄 From the very top:

This is in preparation for #27663, ([MNT]: Move Matplotlib backend mapping from IPython and support backends self-registering)

Yes, this PR is getting the ducks lined up ready for the real work in my next PR.

@ianthomas23
Copy link
Member Author

The reduction is code coverage is due to changes I have had to make to _safe_pyplot_import. This function is not tested and is not used anywhere in the Matplotlib code base. It was added in #18316 (August 2020) and the one and only use of it was removed in #22925 (May 2022). So given that the function is private (leading underscore), not used and not tested, I think it should be removed.

@tacaswell tacaswell added the Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. label Mar 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. topic: canvas and figure manager topic: pyplot API topic: rcparams
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0