8000 Make it possible to add mpl.rcParams to itself or deepcopy · matplotlib/matplotlib@4d01858 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4d01858

Browse files
committed
Make it possible to add mpl.rcParams to itself or deepcopy
Before it was not possible to set all rcParams to mpl.rcParams or use copy.deepcopy on mpl.rcParams. There were two problems: 1. validate_bool_maybe_none(None) was raising ValueError -> fixed by accepting this value 2. svg.embed_char_paths was deprecated by svg.fonttype but both have different valid values (bool vs strings). -> fixed by adding a "value translation" lambda to deprecatedmap which translates the boolean values to the string values of svg.fonttype. Also changed all validators, which accept None to check strings without case ("none" vs "None"). Test for this: mpl.tests.test_rcparams.test_Bug_2543() Closes: #2543
1 parent aefa98c commit 4d01858

File tree

3 files changed

+64
-19
lines changed

3 files changed

+64
-19
lines changed

lib/matplotlib/__init__.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -762,14 +762,14 @@ def matplotlib_fname():
762762

763763

764764
_deprecated_map = {
765-
'text.fontstyle': 'font.style',
766-
'text.fontangle': 'font.style',
767-
'text.fontvariant': 'font.variant',
768-
'text.fontweight': 'font.weight',
769-
'text.fontsize': 'font.size',
770-
'tick.size' : 'tick.major.size',
771-
'svg.embed_char_paths' : 'svg.fonttype',
772-
'savefig.extension' : 'savefig.format'
765+
'text.fontstyle': ('font.style',lambda x: x),
766+
'text.fontangle': ('font.style',lambda x: x),
767+
'text.fontvariant': ('font.variant',lambda x: x),
768+
'text.fontweight': ('font.weight',lambda x: x),
769+
'text.fontsize': ('font.size',lambda x: x),
770+
'tick.size' : ('tick.major.size',lambda x: x),
771+
'svg.embed_char_paths' : ('svg.fonttype',lambda x: "path" if x else "none"),
772+
'savefig.extension' : ('savefig.format',lambda x: x),
773773
}
774774

775775
_deprecated_ignore_map = {
@@ -793,24 +793,28 @@ class RcParams(dict):
793793
def __setitem__(self, key, val):
794794
try:
795795
if key in _deprecated_map:
796-
alt = _deprecated_map[key]
797-
warnings.warn(self.msg_depr % (key, alt))
798-
key = alt
796+
alt_key, alt_val = _deprecated_map[key]
797+
warnings.warn(self.msg_depr % (key, alt_key))
798+
key = alt_key
799+
val = alt_val(val)
799800
elif key in _deprecated_ignore_map:
800801
alt = _deprecated_ignore_map[key]
801802
warnings.warn(self.msg_depr_ignore % (key, alt))
802803
return
803-
cval = self.validate[key](val)
804+
try:
805+
cval = self.validate[key](val)
806+
except ValueError as ve:
807+
raise ValueError("Key %s: %s" % (key, str(ve)))
804808
dict.__setitem__(self, key, cval)
805809
except KeyError:
806810
raise KeyError('%s is not a valid rc parameter.\
807811
See rcParams.keys() for a list of valid parameters.' % (key,))
808812

809813
def __getitem__(self, key):
810814
if key in _deprecated_map:
811-
alt = _deprecated_map[key]
812-
warnings.warn(self.msg_depr % (key, alt))
813-
key = alt
815+
alt_key, alt_val = _deprecated_map[key]
816+
warnings.warn(self.msg_depr % (key, alt_key))
817+
key = alt_key
814818
elif key in _deprecated_ignore_map:
815819
alt = _deprecated_ignore_map[key]
816820
warnings.warn(self.msg_depr_ignore % (key, alt))

lib/matplotlib/rcsetup.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def validate_bool_maybe_none(b):
8888
'Convert b to a boolean or raise'
8989
if isinstance(b, six.string_types):
9090
b = b.lower()
91-
if b == 'none':
91+
if b is None or b == 'none':
9292
return None
9393
if b in ('t', 'y', 'yes', 'on', 'true', '1', 1, True):
9494
return True
@@ -336,7 +336,6 @@ def update_savefig_format(value):
336336
def validate_ps_distiller(s):
337337
if isinstance(s, six.string_types):
338338
s = s.lower()
339-
340339
if s in ('none', None):
341340
return None
342341
elif s in ('false', False):
@@ -395,7 +394,7 @@ def deprecate_svg_embed_char_paths(value):
395394
warnings.warn("svg.embed_char_paths is deprecated. Use "
396395
"svg.fonttype instead.")
397396

398-
validate_svg_fonttype = ValidateInStrings('fonttype',
397+
validate_svg_fonttype = ValidateInStrings('svg.fonttype',
399398
['none', 'path', 'svgfont'])
400399

401400

@@ -430,7 +429,9 @@ def validate_bbox(s):
430429
raise ValueError("bbox should be 'tight' or 'standard'")
431430

432431
def validate_sketch(s):
433-
if s == 'None' or s is None:
432+
if isinstance(s, six.string_types):
433+
s = s.lower()
434+
if s == 'none' or s is None:
434435
return None
435436
if isinstance(s, six.string_types):
436437
result = tuple([float(v.strip()) for v in s.split(',')])

lib/matplotlib/tests/test_rcparams.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
import six
55

66
import os
7+
import sys
78

89
import matplotlib as mpl
910
from matplotlib.tests import assert_str_equal
11+
from nose.tools import assert_true, assert_raises
12+
import nose
1013

1114

1215
mpl.rc('text', usetex=False)
@@ -92,6 +95,43 @@ def test_RcParams_class():
9295
assert ['font.cursive', 'font.size'] == sorted(rc.find_all('i[vz]').keys())
9396
assert ['font.family'] == list(six.iterkeys(rc.find_all('family')))
9497

98+
def test_Bug_2543():
99+
# Test that it possible to add all values to itself / deepcopy
100+
# This was not possible because validate_bool_maybe_none did not
101+
# accept None as an argument.
102+
# https://github.com/matplotlib/matplotlib/issues/2543
103+
with mpl.rc_context():
104+
_copy = mpl.rcParams.copy()
105+
for key in six.iterkeys(_copy):
106+
mpl.rcParams[key] = _copy[key]
107+
mpl.rcParams['text.dvipnghack'] = None
108+
with mpl.rc_context():
109+
from copy import deepcopy
110+
_deep_copy = deepcopy(mpl.rcParams)
111+
from matplotlib.rcsetup import validate_bool_maybe_none, validate_bool
112+
# real test is that this does not raise
113+
assert_true(validate_bool_maybe_none(None) is None)
114+
assert_true(validate_bool_maybe_none("none") is None)
115+
_fonttype = mpl.rcParams['svg.fonttype']
116+
assert_true(_fonttype == mpl.rcParams['svg.embed_char_paths'])
117+
with mpl.rc_context():
118+
mpl.rcParams['svg.embed_char_paths'] = False
119+
assert_true(mpl.rcParams['svg.fonttype'] == "none")
120+
121+
def test_Bug_2543_newer_python():
122+
# only split from above because of the usage of assert_raises
123+
# as a context manager, which only works in 2.7 and above
124+
if sys.version_info[:2] < (2, 7):
125+
raise nose.SkipTest("assert_raises as context manager not supported with Python < 2.7")
126+
from matplotlib.rcsetup import validate_bool_maybe_none, validate_bool
127+
with assert_raises(ValueError):
128+
validate_bool_maybe_none("blah")
129+
with assert_raises(ValueError):
130+
validate_bool(None)
131+
with assert_raises(ValueError):
132+
with mpl.rc_context():
133+
mpl.rcParams['svg.fonttype'] = True
134+
95135
if __name__ == '__main__':
96136
import nose
97137
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

0 commit comments

Comments
 (0)
0