-
-
Notifications
You must be signed in to change notification settings - Fork 8.1k
DOC: Introduce backend versions #30777
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
base: main
Are you sure you want to change the base?
Conversation
57555a5 to
61fa0d9
Compare
|
If we choose to do this (which is not something I'm not really convinced of, as I've mentioned in #30559, but I agree it's low cost), then I think the version numbers should just match the Matplotlib release numbers where backend API changes occur and we should just have a table listing changes to the backend API, e.g. the current backend API could be 3.8 if (hypothetically) mpl3.8 was the last release where a breaking change occurred. |
|
I believe we should have a dedicated backend version scheme independent of matplotlib version numbers, because we want to communicate EffVer semantics on the backend. That’s not possible when just taking the matplotlib version number. |
|
My vote would be that going with Matplotlib major versions would be a lot less confusing. But maybe there are other projects that version subsets of their APIs differently from their project version? |
|
When you look at REST APIs, explicit versioning of the API is common and good practice. I'd argure that our backend API is semantically quite the same. |
|
Can you elaborate - I don't see the analogy. We have one backend API, and its versions will only change with Matplotlib versions? Or am I misunderstanding? |
|
The point is that you explicitly version the API. With EffVer (or SemVer) on the API, you have a direct insight on whether and how much the API has changed. |
|
I am in favor of adding a version on the backends (like we do with on the fontcache). The point is for backends to communicate to us what API they are exposing not what API we are promising. Some questions:
I will defer to @timhoffm on if you want any elevated review on this. |
|
I think this would be easier to reason about if it follows the MPL version number. I do see the analogy to the font cache that this is for others to inform us about what version they want to use and not our API promise to them. One question I have is in regards to whether this could be indicated somehow in the backend registration process instead? When a backend wants to register with us, they could declare what features/API they want to agree to during that process and we wouldn't need explicit versioning, but rather some mechanism to indicate feature sets supported by a backend. |
|
I think the font cache is internal to stop us from trying to use an old font cache on a new version of Matplotlib. We could have used any unique ID? Perhaps this issue would be clarified by a sample of what we think downstream libraries will communicate to their users about these backend versions? |
Exactly.
just an increasing number is fundamentally enough. However, we may consider using EffVer (macro, meso) to communicate how much change happens between versions, in particular how much effort it will be to migrate to the next version - this is what I've intended with the number scheme in this PR. (Note: micro versions are not needed / don't make sense for an API). For example, I'd consider the addition of If we think we don't need that distinction a simple increasing number is good enough. But I would then really just count and not use a matplotlib version number.
They can't, and in general it's not trivial, because to leave us with all degrees of freedom, if a module wanted to provide multiple API versions, they'd have to do each API under a separate namespace. |
While that is possible, I think this would be over-engineering. We would need to define features or feature-sets marked with distinct specifiers. Essentially, the proposed versioning is a coarse feature set. Every more granualar distinction would need to be defined up-front by use (what can backends opt-into or not). |
|
Looking at this again I still don't see how this really helps. Right now:
With the proposed change here:
(By the way, the claim that the backend API has not changed since mpl1.0 is almost certainly not true.) |
IMHO we should communicate our API explicitly. "Look at our source code to understand our API" is not good enough, in particular if you want to support many versions. I minimally require that we have an explicit documentation which API is supported in which version of Matplotlib in one central place. You can do this without versioning, but IMHO attaching an ID to specific states of the API helps with clarity. Determining how to call the third party backend from our side is a separate topic. Sniffing is fundamentally viable. It's a bit more flexile but OTOH a bit more effort on our side and more fragile - it's comparable to dynamic class attibutes. I claim that we/backends don't need that extra flexibility and life would be easier without sniffing. If you really think we need more flexibility than stating a single API version, I'd rather have the backend decleare support for predfined capabilities and we call it based on that rather than trying to sniff them out. |
In theory that is would certainly be better, but in practice this is simply not the case. There are APIs such as _iter_collection() which are effectively not documented but need to be understood to correctly implement a backend. IIRC there are also some rather obscure points regarding image resolution in vector output.
Note that there are already some methods that are here to declare capabilities, e.g. option_image_nocomposite() or option_scale_image(). |
That sounds like we should give up on specifying the backend API. IMHO that would be a poor choice. Only small changes would be possible, will be cumbersome (sniffing) and will lack adoption with third party backends (discoverability and documentation). t.b.h. I don’t quite understand why declining the backend API and giving it a name in form of a version number sees so much reservation. IMHO there‘s little to loose here, but some potential good gains. |
|
I'm not saying that we should not better define the API. Quite the contrary, that would be great. (And certainly, trying to fully spec the backend API is not a fun task, and I'm not providing any help in that direction either.) |
I'm happy to leave the past unspecified if we are not sure about past changes. I would want to give the current state of the API (what is used in 3.10) an ID. - I don't really care on the exact spelling 1.0 or 0.1 or whatever, as long as it's not semantically tied to the library version number. I want this independent ID so that we can state that multiple library versions have the same API, so that it's easier to indicate changes or non-changes on the backend API. I stating a supported MATPLOTLIB_BACKEND_API_VERSION by 3rd party backends seems overly restrictive, we can defer the discussion on wether we'll always sniff the API or come up with patterns via which 3rd party backends can declare their API. |
Sure, let's stick to that for now. I just realized that another possible point of inspiration for designing this interface is the numpy array API standard (NEP 47). Obviously the backend API is not at the same scale, but the idea is the same: there's a central library (here, matplotlib) that provides some objects (canvases, renderers -- compare with numpy arrays) with an API that can be directly used by end users (well almost directly for matplotlib's case, although people do poke at canvases directly) or via helper functions, and a desire that third-party backends can also provide similar objects that can be swapped in to replace the central library's objects. |
61fa0d9 to
ca972d1
Compare
|
@anntzer is the new wording acceptable to you? |
ca972d1 to
bc1f4f0
Compare
|
|
||
| Backend API versions | ||
| -------------------- | ||
| Matplotlib commits to maintain strong backward compatibility on backends. Nevertheless, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Matplotlib aims to maintain backwards compatibility" sounds strong enough? I don't think we really make qualitatively stronger guarantees than for normal APIs (we are perhaps just a bit more careful with the changes because the deprecations are (currently) more annoying to write due to the use of introspection...).
anntzer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor word choice suggestions, but I agree with the general idea.
bc1f4f0 to
029449d
Compare
029449d to
7de667c
Compare
|
I think this should have at least 2 approvals. So leaving open. |
Closes #30559.
As explained in #30559, I believe this will help us mid-term to evolve the backend API. It's currently unused because the 1.1 API is detected via introspection. But we don't want to depend on introspection in the future.
Note: Introducing backend versioning is low-risk. Worst case is that we don't need this versioning and discard it again later.