Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6342bed

Browse files
committed
help
1 parent a44290f commit 6342bed

File tree

5 files changed

+50
-87
lines changed

5 files changed

+50
-87
lines changed

lib/matplotlib/__init__.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -765,8 +765,12 @@ def __getitem__(self, key):
765765
plt.switch_backend(rcsetup._auto_backend_sentinel)
766766

767767
elif key == "path.effects" and self is globals().get("rcParams"):
768-
# to avoid circular imports
769-
return self._load_path_effects()
768+
# defers loading of patheffects to avoid circular imports
769+
import matplotlib.patheffects as path_effects
770+
771+
return [pe if isinstance(pe, path_effects.AbstractPathEffect)
772+
else getattr(path_effects, pe[0])(**pe[1])
773+
for pe in self._get('path.effects')]
770774

771775
return self._get(key)
772776

@@ -818,14 +822,6 @@ def copy(self):
818822
rccopy._set(k, self._get(k))
819823
return rccopy
820824

821-
def _load_path_effects(self):
822-
"""defers loading of patheffects to avoid circular imports"""
823-
import matplotlib.patheffects as path_effects
824-
825-
return [pe if isinstance(pe, path_effects.AbstractPathEffect)
826-
else getattr(path_effects, pe.pop('name'))(**pe)
827-
for pe in copy.deepcopy(self._get('path.effects'))]
828-
829825

830826
def rc_params(fail_on_error=False):
831827
"""Construct a `RcParams` instance from the default Matplotlib rc file."""

lib/matplotlib/mpl-data/stylelib/xkcd.mplstyle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ figure.facecolor: white
2727

2828
# path
2929
path.sketch : 1, 100, 2
30-
path.effects: {'name': 'withStroke', 'linewidth': 4, 'foreground': 'w' }
30+
path.effects: ('withStroke', {'linewidth': 4, 'foreground': 'w' })

lib/matplotlib/rcsetup.py

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -133,31 +133,6 @@ def validate_any(s):
133133
validate_anylist = _listify_validator(validate_any)
134134

135135

136-
def validate_anydict(allow_none=True, required_keys=None):
137-
"""Validate dictionary, check if keys are missing"""
138-
139-
required_keys = required_keys if required_keys else set()
140-
141-
def _validate_dict(d):
142-
try:
143-
d = ast.literal_eval(d)
144-
except ValueError:
145-
pass
146-
147-
if allow_none and d is None:
148-
return d
149-
150-
if isinstance(d, dict):
151-
if missing_keys := (required_keys - d.keys()):
152-
raise ValueError(f"Missing required key: {missing_keys!r}")
153-
return d
154-
155-
raise ValueError(f"Input {d!r} must be a dictionary {{'k': v}} "
156-
f"{'or None' if allow_none else ''}")
157-
158-
return _validate_dict
159-
160-
161136
def _validate_date(s):
162137
try:
163138
np.datetime64(s)
@@ -599,18 +574,39 @@ def validate_path_effects(s):
599574
if not s:
600575
return []
601576

602-
_validate = validate_anydict(allow_none=True, required_keys={'name'})
603-
# string list of dict {k1: 1, k2:2}, {k1:2}
604-
# validate_anylist relies on , for parsing so parse here instead
605-
if isinstance(s, str) and s.startswith("{"):
577+
if isinstance(s, str) and s.startswith("("):
606578
s = ast.literal_eval(s)
607-
if isinstance(s, dict):
608-
# list of one dict
609-
return _validate(s)
610579

611-
return [pe if getattr(pe, '__module__', "") == 'matplotlib.patheffects'
612-
else _validate(pe) for pe in validate_anylist(s)]
580+
if not isinstance(s, list): #string tuple list mostly
581+
s = [s]
582+
583+
_validate_name = ValidateInStrings("path.effects",
584+
["Normal",
585+
"PathPatchEffect",
586+
"SimpleLineShadow",
587+
"SimplePatchShadow",
588+
"Stroke",
589+
"TickedStroke",
590+
"withSimplePatchShadow",
591+
"withStroke",
592+
"withTickedStroke"])
593+
path_effects = []
594+
595+
for pe in s:
596+
#patheffects objects
597+
if getattr(pe, '__module__', "") == 'matplotlib.patheffects':
598+
path_effects.append(pe)
599+
continue
600+
601+
if not isinstance(pe, (tuple)):
602+
raise ValueError("Expected a list of tuples of the form: ('function name', {**kwargs})")
603+
604+
if len(pe) == 1:
605+
pe == (pe[0], {})
606+
path_effects.append((_validate_name(pe[0]), pe[1]))
607+
613608

609+
return path_effects
614610

615611
def _validate_greaterthan_minushalf(s):
616612
s = validate_float(s)

lib/matplotlib/rcsetup.pyi

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ class ValidateInStrings:
2929

3030
def validate_any(s: Any) -> Any: ...
3131
def validate_anylist(s: Any) -> list[Any]: ...
32-
def validate_anydict(allow_none: bool = True, required_keys: set[str]|None = None
33-
) -> Callable[[dict[str, Any]|None], dict[str, Any]]: ...
3432
def validate_bool(b: Any) -> bool: ...
3533
def validate_axisbelow(s: Any) -> bool | Literal["line"]: ...
3634
def validate_dpi(s: Any) -> Literal["figure"] | float: ...
@@ -143,7 +141,8 @@ def _validate_linestyle(s: Any) -> LineStyleType: ...
143141
def validate_markeverylist(s: Any) -> list[MarkEveryType]: ...
144142
def validate_bbox(s: Any) -> Literal["tight", "standard"] | None: ...
145143
def validate_sketch(s: Any) -> None | tuple[float, float, float]: ...
146-
def validate_path_effects(s: Any) -> list[AbstractPathEffect] | list[dict]: ...
144+
def validate_path_effects(s: str | list[AbstractPathEffect, Tuple[str,dict]])
145+
-> list[AbstractPathEffect | [Tuple[str, dict]]]: ...
147146
def validate_hatch(s: Any) -> str: ...
148147
def validate_hatchlist(s: Any) -> list[str]: ...
149148
def validate_dashlist(s: Any) -> list[list[float]]: ...

lib/matplotlib/tests/test_rcparams.py

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import numpy as np
1919
from matplotlib.rcsetup import (
20-
validate_anydict,
2120
validate_bool,
2221
validate_color,
2322
validate_colorlist,
@@ -635,35 +634,9 @@ def test_rcparams_legend_loc_from_file(tmpdir, value):
635634
with mpl.rc_context(fname=rc_path):
636635
assert mpl.rcParams["legend.loc"] == value
637636

638-
639-
@pytest.mark.parametrize("allow_none", [True, False])
640-
def test_validate_dict(allow_none):
641-
fval = validate_anydict(allow_none)
642-
assert fval("{'a': 1, 'b': 2}") == {'a': 1, 'b': 2}
643-
with pytest.raises(ValueError, match=r"Input \['a', 'b'\] "):
644-
fval(['a', 'b'])
645-
646-
fval = validate_anydict(allow_none, required_keys={'a'})
647-
assert fval({'a': 1}) == {'a': 1}
648-
with pytest.raises(ValueError, match="Missing required key: {'a'}"):
649-
fval({'b': 1})
650-
651-
652-
def test_validate_dict_none():
653-
assert validate_anydict()(None) is None
654-
assert validate_anydict(required_keys={'a'})(None) is None
655-
656-
with pytest.raises(ValueError,
657-
match=r"Input None must be a dictionary "):
658-
validate_anydict(False)(None)
659-
with pytest.raises(ValueError,
660-
match=r"Input 0 must be a dictionary {'k': v} or None"):
661-
validate_anydict(True)(0)
662-
663-
664-
ped = [{'name': 'Normal'},
665-
{'name': 'Stroke', 'offset': (1, 2)},
666-
{'name': 'withStroke', 'linewidth': 4, 'foreground': 'w'}]
637+
ped = [('Normal', {}),
638+
('Stroke', {'offset': (1, 2)}),
639+
('withStroke', {'linewidth': 4, 'foreground': 'w'})]
667640

668641
pel = [path_effects.Normal(),
669642
path_effects.Stroke((1, 2)),
@@ -677,11 +650,11 @@ def test_path_effects(value):
677650
assert validate_path_effects(value) == value
678651

679652

680-
def test_path_effects_string_dict():
653+
def test_path_effects_string():
681654
"""test list of dicts properly parsed"""
682-
pstr = "{'name': 'Normal'},"
683-
pstr += "{'name': 'Stroke', 'offset': (1, 2)},"
684-
pstr += "{'name': 'withStroke', 'linewidth': 4, 'foreground': 'w'}"
655+
pstr = "('Normal', ), "
656+
pstr += "('Stroke', : {'offset': (1, 2)}),"
657+
pstr += "('withStroke', {'linewidth': 4, 'foreground': 'w'})"
685658
assert validate_path_effects(pstr) == ped
686659

687660

@@ -701,10 +674,10 @@ def test_path_effects_picture(fig_test, fig_ref, fdict, flist):
701674

702675

703676
def test_path_effect_errors():
704-
with pytest.raises(ValueError, match="Missing required key: {'name'}"):
705-
mpl.rcParams['path.effects'] = [{'kwargs': {1, 2, 3}}]
677+
with pytest.raises(ValueError, match=r"Key path.effects: 'Happy'"):
678+
mpl.rcParams['path.effects'] = [("Happy", {'a': 1})]
706679

707-
with pytest.raises(ValueError, match=r"Key path.effects: Input 1 "):
680+
with pytest.raises(ValueError, match="Expected a list of tuples of the form: ('function name', {**kwargs})"):
708681
mpl.rcParams['path.effects'] = [1, 2, 3]
709682

710683

@@ -713,8 +686,7 @@ def test_path_effects_from_file(tmpdir):
713686
# if any of these are not allowed, an exception will be raised.
714687
# test for gh issue #22338
715688
rc_path = tmpdir.join("matplotlibrc")
716-
rc_path.write("path.effects: "
717-
"{'name': 'Normal'}, {'name': 'withStroke', 'linewidth': 2}")
689+
rc_path.write("path.effects: ('Normal', {}), ('withStroke', {'linewidth': 2})")
718690

719691
with mpl.rc_context(fname=rc_path):
720692
assert isinstance(mpl.rcParams["path.effects"][0], path_effects.Normal)

0 commit comments

Comments
 (0)