Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
POC: add validation of formatters to converters#25662
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 ourterms of service andprivacy 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?
Uh oh!
There was an error while loading.Please reload this page.
Conversation
I think this would be valuable: in the case of#24951, the user didn’t originally know about nc-time-axis. They were using xarray, which uses nc-time-axis under the hood. So if the message only said “not this formatter”, it would not be obvious what to do instead. |
Does it make more sense to put validation logic on the formatters (which make a judgement about if they can consume value from a given converter) instead? It would mean that every converter does not have to know about Converters are supposed to go to some unitless value which for values which have a natural 0 is fine (e.g. mass, weight, number of thing, etc) so most converters should work with most formatters . On the other hand time is the most common thing that has no natural 0, the float that comes out of the converter always has to be relative to some point (and with some precision) which is the source of our problems. Thus if our date formatters were very cranky about what converters they can work with we would catch most (all) of the cftime / pandas issues. I think we can add a null I would also suggest letting the validate function/method raise instead of return |
See#24951 (comment) for why I implemented it in this direction.@spencerkclark had indicated a willingness to consider dropping the inheritance afterwards, which would resolve that worry in this particular case. Without doing "no subclasses" I don't know what checks we can do that would catch the current implementation. (which, to be fair, it doesn't do the right thing withouta change, as noted above) As for raising instead of returning bool, that is fair, I was on the fence about that so just picked one to start with. |
I'm not quite following the details here. It pretty quickly got into details about how the warnings are presented etc. However, it sounds like a converter will have to whitelist a bunch of Formatters? What method does the user have to override this if they want to, for instance, write their own Formatter? I'm tending to lean towards@tacaswell opinion that the Formatters should decide what converter(s) they are happy to work with. But, as usually, I'm probably a couple of steps behind following what the idea is here. |
Essentially, the problem is that there is no good way to disallow the "broken" formatter from The original report is someone trying to use our formatter with their converter. That is why I inverted the check. That said, itstill does not succeed in doing what we want without a change downstream. It all kind of breaks down because whatever we implement on our converter is inherited by With this proposed implementation, subclassing would allow users to write their own formatters. (which, admittedly, I don't really like requiring, but I was drawing on the example I have in front of me...) If we can get I don't fully know that the problem of needing to account for the null case (even if only during initialization/setting of the formatter) is actually erased in the other direction either, though... I'd have to think about it a bit more/try it out... |
PR Summary
Closes#24951
Certainly needs tests/docs prior to merge, but opening to further the conversation.
This introduces a method to Converters to validate that a given formatter works with with the Converter.
Currently it is implemented as a staticmethod which returns a bool and then matplotlib warns if that bool is false.
One option that I would consider would be to push the warning into the method, which could then suggest the valid types with a more targetted error message.
I chose a method so that more complicated logiccould be used, but so far all instances I have implemented or considered do simple
isinstance
checks.One alternative if this was sufficient would be to make the thing that gets propegated a list (tuple?) of Formatter classes and then do the isinstance check directly rather than calling the method.
This could potentially also have APIs for registering formatters as valid for a given converter (or just be directly mutable as a list).
The cost, though is that you are limited toonly isinstance checks there.
(Of course with the method implementation, individual classes are free to implement such registration APIs, but lacks standardization)
If the converter is not set, it does not get checked.
Default behavior of ConversionInterface (and any subclasses which do not override the method) is to accept any formatter (i.e. return True indiscriminantly).
Thus except where downstream inherits from
DateConverter
orStrCategoryConverter
it is entirely opt-in to this additional check.Converters that expect essentially just float values (and should work with many different formatters that are not all enumerated) retain default behavior (internally, the example is DecimalConverter).
It is only a warning, not an error, mostly to ensure that if the list is wrong, you can still do what you want.
One slight wrinkle that is perhaps slightly awkward is that the
NullFormatter
does need to returnTrue
as that occurs during some setup/initialization phases (as well as just the semantics that you should be able to useNullFormatter
to disable labels anyway)@spencerkclark I am particularly interested in your opinion here
Here is the appropriate diff for nc-time-axis that I tested with:
The growing pain here is that without the above change, the NetCDFTimeConverter class from
cftime
will warn for thecorrect formatters and not the mpl-default date formatters (that don't work properly).This is because of the
mdates.DateConverter
inheritance that is not overridden without the above diff. As such, not sure there is any path that doesn't inherit the incorrect behavior without a change in nc-time-axis.Since this affects downstream with warnings (not direct errors, at least), I would like to consult with at least the likes of Pandas (xarray's converting/formatting support is largely via nc-time-axis, above).
If there are other downstream projects we should consult with, happy to hear more.
I do not (yet) affirmatively test that the warningis issued, though it did fail a test which sets
FixedFormatter
on a date axis and already ignores a warning against using such withoutFixedLocator
.Questions:
set_formatter
both sufficient and not overzealous?PR Checklist
Documentation and Tests
pytest
passes)Release Notes
.. versionadded::
directive in the docstring and documented indoc/users/next_whats_new/
.. versionchanged::
directive in the docstring and documented indoc/api/next_api_changes/
next_whats_new/README.rst
ornext_api_changes/README.rst