107
107
from . import cbook , rcsetup
108
108
from matplotlib .cbook import MatplotlibDeprecationWarning , sanitize_sequence
109
109
from matplotlib .cbook import mplDeprecation # deprecated
110
- from matplotlib .rcsetup import defaultParams , validate_backend , cycler
110
+ from matplotlib .rcsetup import validate_backend , cycler
111
111
112
112
import numpy
113
113
@@ -524,7 +524,6 @@ def get_data_path(*, _from_rc=None):
524
524
removal = '3.4' )
525
525
path = Path (_from_rc )
526
526
if path .is_dir ():
527
- defaultParams ['datapath' ][0 ] = str (path )
528
527
return str (path )
529
528
else :
530
529
warnings .warn (f"You passed datapath: { _from_rc !r} in your "
@@ -539,7 +538,6 @@ def get_data_path(*, _from_rc=None):
539
538
def _get_data_path ():
540
539
path = Path (__file__ ).with_name ("mpl-data" )
541
540
if path .is_dir ():
542
- defaultParams ['datapath' ][0 ] = str (path )
543
541
return str (path )
544
542
545
543
cbook .warn_deprecated (
@@ -648,9 +646,7 @@ class RcParams(MutableMapping, dict):
648
646
:ref:`customizing-with-matplotlibrc-files`
649
647
"""
650
648
651
- validate = {key : converter
652
- for key , (default , converter ) in defaultParams .items ()
653
- if key not in _all_deprecated }
649
+ validate = rcsetup ._validators
654
650
655
651
# validate values on the way in
656
652
def __init__ (self , * args , ** kwargs ):
@@ -706,6 +702,9 @@ def __getitem__(self, key):
706
702
from matplotlib import pyplot as plt
707
703
plt .switch_backend (rcsetup ._auto_backend_sentinel )
708
704
705
+ elif key == "datapath" :
706
+ return get_data_path ()
707
+
709
708
return dict .__getitem__ (self , key )
710
709
711
710
def __repr__ (self ):
@@ -776,19 +775,31 @@ def _open_file_or_url(fname):
776
775
yield f
777
776
778
777
779
- def _rc_params_in_file (fname , fail_on_error = False ):
778
+ def _rc_params_in_file (fname , transform = lambda x : x , fail_on_error = False ):
780
779
"""
781
780
Construct a `RcParams` instance from file *fname*.
782
781
783
782
Unlike `rc_params_from_file`, the configuration class only contains the
784
783
parameters specified in the file (i.e. default values are not filled in).
784
+
785
+ Parameters
786
+ ----------
787
+ fname : path-like
788
+ The loaded file.
789
+ transform : callable, default: the identity function
790
+ A function called on each individual line of the file to transform it,
791
+ before further parsing.
792
+ fail_on_error : bool, default: False
793
+ Whether invalid entries should result in an exception or a warning.
785
794
"""
795
+
786
796
_error_details_fmt = 'line #%d\n \t "%s"\n \t in file "%s"'
787
797
788
798
rc_temp = {}
789
799
with _open_file_or_url (fname ) as fd :
790
800
try :
791
801
for line_no , line in enumerate (fd , 1 ):
802
+ line = transform (line )
792
803
strippedline = line .split ('#' , 1 )[0 ].strip ()
793
804
if not strippedline :
794
805
continue
@@ -815,7 +826,7 @@ def _rc_params_in_file(fname, fail_on_error=False):
815
826
config = RcParams ()
816
827
817
828
for key , (val , line , line_no ) in rc_temp .items ():
818
- if key in defaultParams :
829
+ if key in rcsetup . _validators :
819
830
if fail_on_error :
820
831
config [key ] = val # try to convert to proper type or raise
821
832
else :
@@ -856,16 +867,13 @@ def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
856
867
in the given file. If False, the configuration class only contains the
857
868
parameters specified in the file. (Useful for updating dicts.)
858
869
"""
859
- config_from_file = _rc_params_in_file (fname , fail_on_error )
870
+ config_from_file = _rc_params_in_file (fname , fail_on_error = fail_on_error )
860
871
861
872
if not use_default_template :
862
873
return config_from_file
863
874
864
- iter_params = defaultParams .items ()
865
875
with cbook ._suppress_matplotlib_deprecation_warning ():
866
- config = RcParams ([(key , default ) for key , (default , _ ) in iter_params
867
- if key not in _all_deprecated ])
868
- config .update (config_from_file )
876
+ config = RcParams ({** rcParamsDefault , ** config_from_file })
869
877
870
878
with cbook ._suppress_matplotlib_deprecation_warning ():
871
879
if config ['datapath' ] is None :
@@ -886,16 +894,28 @@ def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
886
894
return config
887
895
888
896
889
- # this is the instance used by the matplotlib classes
890
- rcParams = rc_params ()
891
-
892
-
897
+ # When constructing the global instances, we need to perform certain updates
898
+ # by explicitly calling the superclass (dict.update, dict.items) to avoid
899
+ # triggering resolution of _auto_backend_sentinel.
900
+ rcParamsDefault = _rc_params_in_file (
901
+ cbook ._get_data_path ("matplotlibrc" ),
902
+ # Strip leading comment.
903
+ transform = lambda line : line [1 :] if line .startswith ("#" ) else line ,
904
+ fail_on_error = True )
905
+ dict .update (rcParamsDefault , rcsetup ._hardcoded_defaults )
906
+ rcParams = RcParams () # The global instance.
907
+ dict .update (rcParams , dict .items (rcParamsDefault ))
908
+ dict .update (rcParams , _rc_params_in_file (matplotlib_fname ()))
893
909
with cbook ._suppress_matplotlib_deprecation_warning ():
894
910
rcParamsOrig = RcParams (rcParams .copy ())
895
- rcParamsDefault = RcParams ([(key , default ) for key , (default , converter ) in
896
- defaultParams .items ()
897
- if key not in _all_deprecated ])
898
-
911
+ # This also checks that all rcParams are indeed listed in the template.
912
+ # Assiging to rcsetup.defaultParams is left only for backcompat.
913
+ defaultParams = rcsetup .defaultParams = {
914
+ # We want to resolve deprecated rcParams, but not backend...
915
+ key : [(rcsetup ._auto_backend_sentinel if key == "backend" else
916
+ rcParamsDefault [key ]),
917
+ validator ]
918
+ for key , validator in rcsetup ._validators .items ()}
899
919
if rcParams ['axes.formatter.use_locale' ]:
900
920
locale .setlocale (locale .LC_ALL , '' )
901
921
0 commit comments