diff --git a/doc/api/next_api_changes/behavior/21031-AL.rst b/doc/api/next_api_changes/behavior/21031-AL.rst new file mode 100644 index 000000000000..ec1a80f9478a --- /dev/null +++ b/doc/api/next_api_changes/behavior/21031-AL.rst @@ -0,0 +1,3 @@ +Setting invalid ``rcParams["date.converter"]`` now raises ValueError +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Previously, invalid values would be ignored with a UserWarning. diff --git a/lib/matplotlib/dates.py b/lib/matplotlib/dates.py index 67aff6270815..2b03ff81678c 100644 --- a/lib/matplotlib/dates.py +++ b/lib/matplotlib/dates.py @@ -1890,44 +1890,32 @@ def axisinfo(self, unit, axis): default_limits=(datemin, datemax)) -class _rcParam_helper: +class _SwitchableDateConverter: """ - This helper class is so that we can set the converter for dates - via the validator for the rcParams `date.converter` and - `date.interval_multiples`. Never instatiated. + Helper converter-like object that generates and dispatches to + temporary ConciseDateConverter or DateConverter instances based on + :rc:`date.converter` and :rc:`date.interval_multiples`. """ - conv_st = 'auto' - int_mult = True - - @classmethod - def set_converter(cls, s): - """Called by validator for rcParams date.converter""" - if s not in ['concise', 'auto']: - raise ValueError('Converter must be one of "concise" or "auto"') - cls.conv_st = s - cls.register_converters() - - @classmethod - def set_int_mult(cls, b): - """Called by validator for rcParams date.interval_multiples""" - cls.int_mult = b - cls.register_converters() - - @classmethod - def register_converters(cls): - """ - Helper to register the date converters when rcParams `date.converter` - and `date.interval_multiples` are changed. Called by the helpers - above. - """ - if cls.conv_st == 'concise': - converter = ConciseDateConverter - else: - converter = DateConverter + @staticmethod + def _get_converter(): + converter_cls = { + "concise": ConciseDateConverter, "auto": DateConverter}[ + mpl.rcParams["date.converter"]] + interval_multiples = mpl.rcParams["date.interval_multiples"] + return converter_cls(interval_multiples=interval_multiples) + + def axisinfo(self, *args, **kwargs): + return self._get_converter().axisinfo(*args, **kwargs) + + def default_units(self, *args, **kwargs): + return self._get_converter().default_units(*args, **kwargs) + + def convert(self, *args, **kwargs): + return self._get_converter().convert(*args, **kwargs) + - interval_multiples = cls.int_mult - convert = converter(interval_multiples=interval_multiples) - units.registry[np.datetime64] = convert - units.registry[datetime.date] = convert - units.registry[datetime.datetime] = convert +units.registry[np.datetime64] = \ + units.registry[datetime.date] = \ + units.registry[datetime.datetime] = \ + _SwitchableDateConverter() diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index a8a54c10dac6..9f6b9d53ca62 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -149,26 +149,6 @@ def validate_bool(b): raise ValueError('Could not convert "%s" to bool' % b) -def _validate_date_converter(s): - if s is None: - return - s = validate_string(s) - if s not in ['auto', 'concise']: - _api.warn_external(f'date.converter string must be "auto" or ' - f'"concise", not "{s}". Check your matplotlibrc') - return - import matplotlib.dates as mdates - mdates._rcParam_helper.set_converter(s) - - -def _validate_date_int_mult(s): - if s is None: - return - s = validate_bool(s) - import matplotlib.dates as mdates - mdates._rcParam_helper.set_int_mult(s) - - def validate_axisbelow(s): try: return validate_bool(s) @@ -1036,10 +1016,9 @@ def _convert_validator_spec(key, conv): "date.autoformatter.second": validate_string, "date.autoformatter.microsecond": validate_string, - # 'auto', 'concise', 'auto-noninterval' - 'date.converter': _validate_date_converter, + 'date.converter': ['auto', 'concise'], # for auto date locator, choose interval_multiples - 'date.interval_multiples': _validate_date_int_mult, + 'date.interval_multiples': validate_bool, # legend properties "legend.fancybox": validate_bool, diff --git a/lib/matplotlib/tests/test_dates.py b/lib/matplotlib/tests/test_dates.py index 3a38516c7272..96a3db173053 100644 --- a/lib/matplotlib/tests/test_dates.py +++ b/lib/matplotlib/tests/test_dates.py @@ -1152,7 +1152,7 @@ def test_change_converter(): fig.canvas.draw() assert ax.get_xticklabels()[0].get_text() == 'Jan 01 2020' assert ax.get_xticklabels()[1].get_text() == 'Jan 15 2020' - with pytest.warns(UserWarning) as rec: + with pytest.raises(ValueError): plt.rcParams['date.converter'] = 'boo'