From b32a06a10c580804f1237bd4ccd575b05109a180 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Wed, 12 Feb 2020 17:02:35 +0100 Subject: [PATCH] Deprecate most ValidateInStrings validators. We can just list the allowed string values in the defaultParams dict (which is actually clearer) and then dynamically generate the corresponding validators; no need to expose them as separate public API (which is not particularly useful anyways because how can you know that it's `validate_fontset` for `mathtext.fontset`, but `validate_mathtext_default` for `mathtext.default`?). --- doc/api/next_api_changes/deprecations.rst | 11 +++ lib/matplotlib/rcsetup.py | 101 ++++++++++++---------- 2 files changed, 68 insertions(+), 44 deletions(-) diff --git a/doc/api/next_api_changes/deprecations.rst b/doc/api/next_api_changes/deprecations.rst index edcba36009c2..834209fa2753 100644 --- a/doc/api/next_api_changes/deprecations.rst +++ b/doc/api/next_api_changes/deprecations.rst @@ -211,3 +211,14 @@ The *clear_temp* parameter and attribute of `.FileMovieWriter` is deprecated. In the future, files placed in a temporary directory (using ``frame_prefix=None``, the default) will be cleared; files placed elsewhere will not. + +Deprecated rcParams validators +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The following validators, defined in `.rcsetup`, are deprecated: +``validate_fontset``, ``validate_mathtext_default``, ``validate_alignment``, +``validate_svg_fontset``, ``validate_pgf_texsystem``, +``validate_movie_frame_fmt``, ``validate_axis_locator``, +``validate_movie_html_fmt``, ``validate_grid_axis``, +``validate_axes_titlelocation``. To test whether an rcParam value would +be acceptable, one can test e.g. ``rc = RcParams(); rc[k] = v`` raises an +exception. diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index 4c2ac7db5aab..d35ed3066a40 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -50,10 +50,12 @@ class ValidateInStrings: - def __init__(self, key, valid, ignorecase=False): + def __init__(self, key, valid, ignorecase=False, *, + _deprecated_since=None): """*valid* is a list of legal strings.""" self.key = key self.ignorecase = ignorecase + self._deprecated_since = _deprecated_since def func(s): if ignorecase: @@ -63,6 +65,10 @@ def func(s): self.valid = {func(k): k for k in valid} def __call__(self, s): + if self._deprecated_since: + name, = (k for k, v in globals().items() if v is self) + cbook.warn_deprecated( + self._deprecated_since, name=name, obj_type="function") if self.ignorecase: s = s.lower() if s in self.valid: @@ -365,7 +371,7 @@ def validate_color(s): validate_colorlist = _listify_validator( validate_color, allow_stringlist=True, doc='return a list of colorspecs') validate_orientation = ValidateInStrings( - 'orientation', ['landscape', 'portrait']) + 'orientation', ['landscape', 'portrait'], _deprecated_since="3.3") def validate_aspect(s): @@ -421,15 +427,15 @@ def validate_font_properties(s): validate_fontset = ValidateInStrings( 'fontset', - ['dejavusans', 'dejavuserif', 'cm', 'stix', 'stixsans', 'custom']) + ['dejavusans', 'dejavuserif', 'cm', 'stix', 'stixsans', 'custom'], + _deprecated_since="3.3") validate_mathtext_default = ValidateInStrings( - 'default', "rm cal it tt sf bf default bb frak scr regular".split()) - - + 'default', "rm cal it tt sf bf default bb frak scr regular".split(), + _deprecated_since="3.3") _validate_alignment = ValidateInStrings( 'alignment', - ['center', 'top', 'bottom', 'baseline', - 'center_baseline']) + ['center', 'top', 'bottom', 'baseline', 'center_baseline'], + _deprecated_since="3.3") def validate_whiskers(s): @@ -648,7 +654,8 @@ def validate_markevery(s): 'upper center', 'center'], ignorecase=True) -validate_svg_fonttype = ValidateInStrings('svg.fonttype', ['none', 'path']) +validate_svg_fonttype = ValidateInStrings( + 'svg.fonttype', ['none', 'path'], _deprecated_since="3.3") def validate_hinting(s): @@ -663,8 +670,9 @@ def validate_hinting(s): raise ValueError("hinting should be 'auto', 'native', 'either' or 'none'") -validate_pgf_texsystem = ValidateInStrings('pgf.texsystem', - ['xelatex', 'lualatex', 'pdflatex']) +validate_pgf_texsystem = ValidateInStrings( + 'pgf.texsystem', ['xelatex', 'lualatex', 'pdflatex'], + _deprecated_since="3.3") def validate_movie_writer(s): @@ -678,12 +686,13 @@ def validate_movie_writer(s): validate_movie_frame_fmt = ValidateInStrings('animation.frame_format', - ['png', 'jpeg', 'tiff', 'raw', 'rgba']) + ['png', 'jpeg', 'tiff', 'raw', 'rgba'], _deprecated_since="3.3") -validate_axis_locator = ValidateInStrings('major', ['minor', 'both', 'major']) +validate_axis_locator = ValidateInStrings( + 'major', ['minor', 'both', 'major'], _deprecated_since="3.3") validate_movie_html_fmt = ValidateInStrings('animation.html', - ['html5', 'jshtml', 'none']) + ['html5', 'jshtml', 'none'], _deprecated_since="3.3") def validate_bbox(s): @@ -736,7 +745,8 @@ def _validate_greaterequal0_lessequal1(s): } -validate_grid_axis = ValidateInStrings('axes.grid.axis', ['x', 'y', 'both']) +validate_grid_axis = ValidateInStrings( + 'axes.grid.axis', ['x', 'y', 'both'], _deprecated_since="3.3") def validate_hatch(s): @@ -984,15 +994,13 @@ def validate_webagg_address(s): raise ValueError("'webagg.address' is not a valid IP address") -validate_axes_titlelocation = ValidateInStrings('axes.titlelocation', - ['left', 'center', 'right']) -_validate_xaxis_labellocation = ValidateInStrings('xaxis.labellocation', - ['left', 'center', 'right']) -_validate_yaxis_labellocation = ValidateInStrings('yaxis.labellocation', - ['bottom', 'center', 'top']) +validate_axes_titlelocation = ValidateInStrings( + 'axes.titlelocation', ['left', 'center', 'right'], _deprecated_since="3.3") -# a map from key -> value, converter +# A map of key -> [value, converter]. +# Converters given as lists are converted to ValidateInStrings immediately +# below. defaultParams = { 'backend': [_auto_backend_sentinel, validate_backend], 'backend_fallback': [True, validate_bool], @@ -1137,16 +1145,19 @@ def validate_webagg_address(s): 'mathtext.it': ['sans:italic', validate_font_properties], 'mathtext.bf': ['sans:bold', validate_font_properties], 'mathtext.sf': ['sans', validate_font_properties], - 'mathtext.fontset': ['dejavusans', validate_fontset], - 'mathtext.default': ['it', validate_mathtext_default], + 'mathtext.fontset': [ + 'dejavusans', + ['dejavusans', 'dejavuserif', 'cm', 'stix', 'stixsans', 'custom']], + 'mathtext.default': [ + 'it', + ['rm', 'cal', 'it', 'tt', 'sf', 'bf', 'default', 'bb', 'frak', 'scr', 'regular']], 'mathtext.fallback_to_cm': [True, validate_bool], 'image.aspect': ['equal', validate_aspect], # equal, auto, a number 'image.interpolation': ['antialiased', validate_string], 'image.cmap': ['viridis', validate_string], # gray, jet, etc. 'image.lut': [256, validate_int], # lookup table - 'image.origin': ['upper', - ValidateInStrings('image.origin', ['upper', 'lower'])], + 'image.origin': ['upper', ['upper', 'lower']], 'image.resample': [True, validate_bool], # Specify whether vector graphics backends will combine all images on a # set of axes into a single composite image @@ -1160,8 +1171,8 @@ def validate_webagg_address(s): 'errorbar.capsize': [0, validate_float], # axis props - 'xaxis.labellocation': ['center', _validate_xaxis_labellocation], # alignment of x axis title - 'yaxis.labellocation': ['center', _validate_yaxis_labellocation], # alignment of y axis title + 'xaxis.labellocation': ['center', ['left', 'center', 'right']], # alignment of x axis title + 'yaxis.labellocation': ['center', ['bottom', 'center', 'top']], # alignment of y axis title # axes props 'axes.axisbelow': ['line', validate_axisbelow], @@ -1176,16 +1187,14 @@ def validate_webagg_address(s): 'axes.titlesize': ['large', validate_fontsize], # fontsize of the # axes title - 'axes.titlelocation': ['center', validate_axes_titlelocation], # alignment of axes title + 'axes.titlelocation': ['center', ['left', 'center', 'right']], # alignment of axes title 'axes.titleweight': ['normal', validate_fontweight], # font weight of axes title 'axes.titlecolor': ['auto', validate_color_or_auto], # font color of axes title 'axes.titlepad': [6.0, validate_float], # pad from axes top to title in points 'axes.grid': [False, validate_bool], # display grid or not - 'axes.grid.which': ['major', validate_axis_locator], # set whether the gid are by - # default draw on 'major' - # 'minor' or 'both' kind of - # axis locator - 'axes.grid.axis': ['both', validate_grid_axis], # grid type: + 'axes.grid.which': ['major', ['minor', 'both', 'major']], # set whether the grid is drawn on + # 'major' 'minor' or 'both' ticks + 'axes.grid.axis': ['both', ['x', 'y', 'both']], # grid type: # 'x', 'y', or 'both' 'axes.labelsize': ['medium', validate_fontsize], # fontsize of the # x any y labels @@ -1214,9 +1223,7 @@ def validate_webagg_address(s): validate_cycler], # If 'data', axes limits are set close to the data. # If 'round_numbers' axes limits are set to the nearest round numbers. - 'axes.autolimit_mode': [ - 'data', - ValidateInStrings('autolimit_mode', ['data', 'round_numbers'])], + 'axes.autolimit_mode': ['data', ['data', 'round_numbers']], 'axes.xmargin': [0.05, _range_validators["0 <= x <= 1"]], 'axes.ymargin': [0.05, _range_validators["0 <= x <= 1"]], @@ -1291,7 +1298,8 @@ def validate_webagg_address(s): # fontsize of the xtick labels 'xtick.labelsize': ['medium', validate_fontsize], 'xtick.direction': ['out', validate_string], # direction of xticks - 'xtick.alignment': ["center", _validate_alignment], + 'xtick.alignment': ['center', + ['center', 'top', 'bottom', 'baseline', 'center_baseline']], 'ytick.left': [True, validate_bool], # draw ticks on the left side 'ytick.right': [False, validate_bool], # draw ticks on the right side @@ -1313,7 +1321,8 @@ def validate_webagg_address(s): # fontsize of the ytick labels 'ytick.labelsize': ['medium', validate_fontsize], 'ytick.direction': ['out', validate_string], # direction of yticks - 'ytick.alignment': ["center_baseline", _validate_alignment], + 'ytick.alignment': ['center_baseline', + ['center', 'top', 'bottom', 'baseline', 'center_baseline']], 'grid.color': ['#b0b0b0', validate_color], # grid color 'grid.linestyle': ['-', _validate_linestyle], # solid @@ -1359,7 +1368,7 @@ def validate_webagg_address(s): 'savefig.dpi': ['figure', validate_dpi], # DPI 'savefig.facecolor': ['white', validate_color], 'savefig.edgecolor': ['white', validate_color], - 'savefig.orientation': ['portrait', validate_orientation], + 'savefig.orientation': ['portrait', ['landscape', 'portrait']], 'savefig.jpeg_quality': [95, validate_int], # value checked by backend at runtime 'savefig.format': ['png', _update_savefig_format], @@ -1389,7 +1398,7 @@ def validate_webagg_address(s): 'pdf.fonttype': [3, validate_fonttype], # 3 (Type3) or 42 (Truetype) # choose latex application for creating pdf files (xelatex/lualatex) - 'pgf.texsystem': ['xelatex', validate_pgf_texsystem], + 'pgf.texsystem': ['xelatex', ['xelatex', 'lualatex', 'pdflatex']], # use matplotlib rc settings for font configuration 'pgf.rcfonts': [True, validate_bool], # provide a custom preamble for the latex process @@ -1398,7 +1407,7 @@ def validate_webagg_address(s): # write raster image data directly into the svg file 'svg.image_inline': [True, validate_bool], # True to save all characters as paths in the SVG - 'svg.fonttype': ['path', validate_svg_fonttype], + 'svg.fonttype': ['path', ['none', 'path']], 'svg.hashsalt': [None, validate_string_or_None], # set this when you want to generate hardcopy docstring @@ -1432,7 +1441,7 @@ def validate_webagg_address(s): 'keymap.copy': [['ctrl+c', 'cmd+c'], validate_stringlist], # Animation settings - 'animation.html': ['none', validate_movie_html_fmt], + 'animation.html': ['none', ['html5', 'jshtml', 'none']], # Limit, in MB, of size of base64 encoded animation in HTML # (i.e. IPython notebook) 'animation.embed_limit': [20, validate_float], @@ -1440,7 +1449,7 @@ def validate_webagg_address(s): 'animation.codec': ['h264', validate_string], 'animation.bitrate': [-1, validate_int], # Controls image format when frames are written to disk - 'animation.frame_format': ['png', validate_movie_frame_fmt], + 'animation.frame_format': ['png', ['png', 'jpeg', 'tiff', 'raw', 'rgba']], # Additional arguments for HTML writer 'animation.html_args': [[], validate_stringlist], # Path to ffmpeg binary. If just binary name, subprocess uses $PATH. @@ -1464,3 +1473,7 @@ def validate_webagg_address(s): # altogether. For that use `matplotlib.style.use('classic')`. '_internal.classic_mode': [False, validate_bool] } +defaultParams = { + k: [default, + ValidateInStrings(k, conv) if isinstance(conv, list) else conv] + for k, (default, conv) in defaultParams.items()}