Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 186f36d

Browse filesBrowse files
authored
Merge pull request #28730 from timhoffm/cleanup-rcParams-upate
MNT: Don't rely on RcParams being a dict subclass in internal code
2 parents 843aadd + 01ceeef commit 186f36d
Copy full SHA for 186f36d

File tree

Expand file treeCollapse file tree

3 files changed

+41
-16
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+41
-16
lines changed

‎lib/matplotlib/__init__.py

Copy file name to clipboardExpand all lines: lib/matplotlib/__init__.py
+35-13Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,35 @@ def _get(self, key):
712712
"""
713713
return dict.__getitem__(self, key)
714714

715+
def _update_raw(self, other_params):
716+
"""
717+
Directly update the data from *other_params*, bypassing deprecation,
718+
backend and validation logic on both sides.
719+
720+
This ``rcParams._update_raw(params)`` replaces the previous pattern
721+
``dict.update(rcParams, params)``.
722+
723+
Parameters
724+
----------
725+
other_params : dict or `.RcParams`
726+
The input mapping from which to update.
727+
"""
728+
if isinstance(other_params, RcParams):
729+
other_params = dict.items(other_params)
730+
dict.update(self, other_params)
731+
732+
def _ensure_has_backend(self):
733+
"""
734+
Ensure that a "backend" entry exists.
735+
736+
Normally, the default matplotlibrc file contains *no* entry for "backend" (the
737+
corresponding line starts with ##, not #; we fill in _auto_backend_sentinel
738+
in that case. However, packagers can set a different default backend
739+
(resulting in a normal `#backend: foo` line) in which case we should *not*
740+
fill in _auto_backend_sentinel.
741+
"""
742+
dict.setdefault(self, "backend", rcsetup._auto_backend_sentinel)
743+
715744
def __setitem__(self, key, val):
716745
try:
717746
if key in _deprecated_map:
@@ -961,24 +990,17 @@ def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
961990
return config
962991

963992

964-
# When constructing the global instances, we need to perform certain updates
965-
# by explicitly calling the superclass (dict.update, dict.items) to avoid
966-
# triggering resolution of _auto_backend_sentinel.
967993
rcParamsDefault = _rc_params_in_file(
968994
cbook._get_data_path("matplotlibrc"),
969995
# Strip leading comment.
970996
transform=lambda line: line[1:] if line.startswith("#") else line,
971997
fail_on_error=True)
972-
dict.update(rcParamsDefault, rcsetup._hardcoded_defaults)
973-
# Normally, the default matplotlibrc file contains *no* entry for backend (the
974-
# corresponding line starts with ##, not #; we fill on _auto_backend_sentinel
975-
# in that case. However, packagers can set a different default backend
976-
# (resulting in a normal `#backend: foo` line) in which case we should *not*
977-
# fill in _auto_backend_sentinel.
978-
dict.setdefault(rcParamsDefault, "backend", rcsetup._auto_backend_sentinel)
998+
rcParamsDefault._update_raw(rcsetup._hardcoded_defaults)
999+
rcParamsDefault._ensure_has_backend()
1000+
9791001
rcParams = RcParams() # The global instance.
980-
dict.update(rcParams, dict.items(rcParamsDefault))
981-
dict.update(rcParams, _rc_params_in_file(matplotlib_fname()))
1002+
rcParams._update_raw(rcParamsDefault)
1003+
rcParams._update_raw(_rc_params_in_file(matplotlib_fname()))
9821004
rcParamsOrig = rcParams.copy()
9831005
with _api.suppress_matplotlib_deprecation_warning():
9841006
# This also checks that all rcParams are indeed listed in the template.
@@ -1190,7 +1212,7 @@ def rc_context(rc=None, fname=None):
11901212
rcParams.update(rc)
11911213
yield
11921214
finally:
1193-
dict.update(rcParams, orig) # Revert to the original rcs.
1215+
rcParams._update_raw(orig) # Revert to the original rcs.
11941216

11951217

11961218
def use(backend, *, force=True):

‎lib/matplotlib/__init__.pyi

Copy file name to clipboardExpand all lines: lib/matplotlib/__init__.pyi
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ class RcParams(dict[str, Any]):
7070
def __init__(self, *args, **kwargs) -> None: ...
7171
def _set(self, key: str, val: Any) -> None: ...
7272
def _get(self, key: str) -> Any: ...
73+
74+
def _update_raw(self, other_params: dict | RcParams) -> None: ...
75+
76+
def _ensure_has_backend(self) -> None: ...
7377
def __setitem__(self, key: str, val: Any) -> None: ...
7478
def __getitem__(self, key: str) -> Any: ...
7579
def __iter__(self) -> Generator[str, None, None]: ...

‎lib/matplotlib/pyplot.py

Copy file name to clipboardExpand all lines: lib/matplotlib/pyplot.py
+2-3Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,7 @@ def switch_backend(newbackend: str) -> None:
410410
switch_backend("agg")
411411
rcParamsOrig["backend"] = "agg"
412412
return
413-
# have to escape the switch on access logic
414-
old_backend = dict.__getitem__(rcParams, 'backend')
413+
old_backend = rcParams._get('backend') # get without triggering backend resolution
415414

416415
module = backend_registry.load_backend_module(newbackend)
417416
canvas_class = module.FigureCanvas
@@ -841,7 +840,7 @@ def xkcd(
841840
"xkcd mode is not compatible with text.usetex = True")
842841

843842
stack = ExitStack()
844-
stack.callback(dict.update, rcParams, rcParams.copy()) # type: ignore[arg-type]
843+
stack.callback(rcParams._update_raw, rcParams.copy()) # type: ignore[arg-type]
845844

846845
from matplotlib import patheffects
847846
rcParams.update({

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.