@@ -736,7 +736,7 @@ def __getitem__(self, key):
736736 Return an `rc_matplotlib` or `rc_proplot` setting using dictionary notation
737737 (e.g., ``value = pplt.rc[name]``).
738738 """
739- key = self ._validate_key (key ) # might issue proplot removed/renamed error
739+ key , _ = self ._validate_key (key ) # might issue proplot removed/renamed error
740740 try :
741741 return rc_proplot [key ]
742742 except KeyError :
@@ -748,7 +748,7 @@ def __setitem__(self, key, value):
748748 Modify an `rc_matplotlib` or `rc_proplot` setting using dictionary notation
749749 (e.g., ``pplt.rc[name] = value``).
750750 """
751- kw_proplot , kw_matplotlib = self ._item_dicts (key , value )
751+ kw_proplot , kw_matplotlib = self ._get_item_dicts (key , value )
752752 rc_proplot .update (kw_proplot )
753753 rc_matplotlib .update (kw_matplotlib )
754754
@@ -782,10 +782,10 @@ def __enter__(self):
782782 )
783783 context = self ._context [- 1 ]
784784 kwargs = context .kwargs
785- rc_new = context .rc_new # used for context-based _item_context
785+ rc_new = context .rc_new # used for context-based _get_item_context
786786 rc_old = context .rc_old # used to re-apply settings without copying whole dict
787787 for key , value in kwargs .items ():
788- kw_proplot , kw_matplotlib = self ._item_dicts (key , value )
788+ kw_proplot , kw_matplotlib = self ._get_item_dicts (key , value )
789789 for rc_dict , kw_new in zip (
790790 (rc_proplot , rc_matplotlib ),
791791 (kw_proplot , kw_matplotlib ),
@@ -804,42 +804,11 @@ def __exit__(self, *args): # noqa: U100
804804 )
805805 context = self ._context [- 1 ]
806806 for key , value in context .rc_old .items ():
807- kw_proplot , kw_matplotlib = self ._item_dicts (key , value )
807+ kw_proplot , kw_matplotlib = self ._get_item_dicts (key , value )
808808 rc_proplot .update (kw_proplot )
809809 rc_matplotlib .update (kw_matplotlib )
810810 del self ._context [- 1 ]
811811
812- @staticmethod
813- def _validate_key (key ):
814- """
815- Ensure string and convert keys with omitted dots.
816- """
817- if not isinstance (key , str ):
818- raise KeyError (f'Invalid key { key !r} . Must be string.' )
819- if '.' not in key :
820- key = rcsetup ._rc_nodots .get (key , key )
821- key = rc_proplot ._check_key (key ) # may issue deprecation warning
822- return key .lower ()
823-
824- @staticmethod
825- def _validate_value (key , value ):
826- """
827- Convert numpy ndarray to list and validate if possible.
828- """
829- # NOTE: Ideally would implicitly validate on subsequent assignment to rc
830- # dictionaries, but must explicitly do it here, so _item_dicts can 'sync'
831- # settings with children (e.g. multiplying tick widths by width ratios)
832- # and so _load_file() can catch errors and emit warnings before assignment.
833- if isinstance (value , np .ndarray ):
834- value = value .item () if value .size == 1 else value .tolist ()
835- validate = getattr (rc_matplotlib , 'validate' , None )
836- validate_proplot = rc_proplot ._validate
837- if validate is not None and key in validate : # guard against API change
838- value = validate [key ](value )
839- elif key in validate_proplot :
840- value = validate_proplot [key ](value )
841- return value
842-
843812 def _init (self , * , local , user , default , skip_cycle = False ):
844813 """
845814 Initialize the configurator.
@@ -854,7 +823,7 @@ def _init(self, *, local, user, default, skip_cycle=False):
854823 rc_matplotlib .update (rcsetup ._rc_matplotlib_default )
855824 rc_proplot .update (rcsetup ._rc_proplot_default )
856825 for key , value in rc_proplot .items ():
857- kw_proplot , kw_matplotlib = self ._item_dicts (
826+ kw_proplot , kw_matplotlib = self ._get_item_dicts (
858827 key , value , skip_cycle = skip_cycle
859828 )
860829 rc_matplotlib .update (kw_matplotlib )
@@ -875,12 +844,49 @@ def _init(self, *, local, user, default, skip_cycle=False):
875844 continue
876845 self .load (path )
877846
878- def _item_context (self , key , mode = None ):
847+ @staticmethod
848+ def _validate_key (key , value = None ):
849+ """
850+ Validate setting names and handle `rc_proplot` deprecations.
851+ """
852+ # NOTE: Not necessary to check matplotlib key here because... not sure why.
853+ # Think deprecated matplotlib keys are not involved in any synced settings.
854+ # Also note _check_key includes special handling for some renamed keys.
855+ if not isinstance (key , str ):
856+ raise KeyError (f'Invalid key { key !r} . Must be string.' )
857+ key = key .lower ()
858+ if '.' not in key :
859+ key = rcsetup ._rc_nodots .get (key , key )
860+ key , value = rc_proplot ._check_key (key , value ) # may issue deprecation warning
861+ return key , value
862+
863+ @staticmethod
864+ def _validate_value (key , value ):
865+ """
866+ Validate setting values and convert numpy ndarray to list if possible.
867+ """
868+ # NOTE: Ideally would implicitly validate on subsequent assignment to rc
869+ # dictionaries, but must explicitly do it here, so _get_item_dicts can
870+ # work with e.g. 'tick.lenratio', so _get_item_dicts does not have to include
871+ # deprecated name handling in its if statements, and so _load_file can
872+ # catch errors and emit warnings with line number indications as files
873+ # are being read rather than after the end of the file reading.
874+ if isinstance (value , np .ndarray ):
875+ value = value .item () if value .size == 1 else value .tolist ()
876+ validate_matplotlib = getattr (rc_matplotlib , 'validate' , None )
877+ validate_proplot = rc_proplot ._validate
878+ if validate_matplotlib is not None and key in validate_matplotlib :
879+ value = validate_matplotlib [key ](value )
880+ elif key in validate_proplot :
881+ value = validate_proplot [key ](value )
882+ return value
883+
884+ def _get_item_context (self , key , mode = None ):
879885 """
880886 As with `~Configurator.__getitem__` but the search is limited based
881887 on the context mode and ``None`` is returned if the key is not found.
882888 """
883- key = self ._validate_key (key )
889+ key , _ = self ._validate_key (key )
884890 if mode is None :
885891 mode = self ._context_mode
886892 cache = tuple (context .rc_new for context in self ._context )
@@ -902,14 +908,14 @@ def _item_context(self, key, mode=None):
902908 if mode == 0 : # otherwise return None
903909 raise KeyError (f'Invalid rc setting { key !r} .' )
904910
905- def _item_dicts (self , key , value , skip_cycle = False ):
911+ def _get_item_dicts (self , key , value , skip_cycle = False ):
906912 """
907913 Return dictionaries for updating the `rc_proplot` and `rc_matplotlib`
908914 properties associated with this key. Used when setting items, entering
909915 context blocks, or loading files.
910916 """
911917 # Get validated key, value, and child keys
912- key = self ._validate_key (key )
918+ key , value = self ._validate_key (key , value )
913919 value = self ._validate_value (key , value )
914920 keys = (key ,) + rcsetup ._rc_children .get (key , ()) # settings to change
915921 contains = lambda * args : any (arg in keys for arg in args ) # noqa: E731
@@ -1016,7 +1022,7 @@ def _item_dicts(self, key, value, skip_cycle=False):
10161022 return kw_proplot , kw_matplotlib
10171023
10181024 @staticmethod
1019- def _axisbelow_to_zorder (axisbelow ):
1025+ def _get_axisbelow_zorder (axisbelow ):
10201026 """
10211027 Convert the `axisbelow` string to its corresponding `zorder`.
10221028 """
@@ -1112,7 +1118,7 @@ def _get_gridline_props(self, which='major', native=True, rebuild=False):
11121118 if native : # this is a native plot so use set_axisbelow() down the line
11131119 kwlines ['axisbelow' ] = axisbelow
11141120 else : # this is a geographic plot so apply with zorder
1115- kwlines ['zorder' ] = self ._axisbelow_to_zorder (axisbelow )
1121+ kwlines ['zorder' ] = self ._get_axisbelow_zorder (axisbelow )
11161122 return kwlines
11171123
11181124 def _get_label_props (self , native = True , ** kwargs ):
@@ -1349,8 +1355,8 @@ def context(self, *args, mode=0, file=None, **kwargs):
13491355 file : path-like, optional
13501356 Filename from which settings should be loaded.
13511357 **kwargs
1352- `rc` names and values passed as keyword arguments. If the
1353- name has dots, simply omit them.
1358+ `rc` names and values passed as keyword arguments.
1359+ If the name has dots, simply omit them.
13541360
13551361 Other parameters
13561362 ----------------
@@ -1363,16 +1369,16 @@ def context(self, *args, mode=0, file=None, **kwargs):
13631369
13641370 * ``mode=0``: Matplotlib's `rc_matplotlib` settings
13651371 and proplot's `rc_proplot` settings are all returned,
1366- whether they are local to the "with as" block.
1372+ whether or not they are local to the "with as" block.
13671373 * ``mode=1``: Matplotlib's `rc_matplotlib` settings are only
13681374 returned if they are local to the "with as" block. For example,
13691375 if :rcraw:`axes.titlesize` was passed to `~Configurator.context`,
13701376 then ``pplt.rc.find('axes.titlesize', context=True)`` will return
1371- this value, but ``pplt.rc.find('axes.titleweight', context=True)``
1372- will return ``None``.
1377+ this value, but ``pplt.rc.find('axes.titleweight', context=True)`` will
1378+ return ``None``. This is used internally when instantiating axes .
13731379 * ``mode=2``: Matplotlib's `rc_matplotlib` settings and proplot's
13741380 `rc_proplot` settings are only returned if they are local to the
1375- "with as" block.
1381+ "with as" block. This is used internally when formatting axes.
13761382
13771383 Note
13781384 ----
@@ -1451,7 +1457,7 @@ def category(self, cat, *, trimcat=True, context=False):
14511457 for key in self :
14521458 if not re .match (fr'\A{ cat } \.[^.]+\Z' , key ):
14531459 continue
1454- value = self ._item_context (key , None if context else 0 )
1460+ value = self ._get_item_context (key , None if context else 0 )
14551461 if value is None :
14561462 continue
14571463 if trimcat :
@@ -1480,7 +1486,7 @@ def fill(self, props, *, context=False):
14801486 """
14811487 kw = {}
14821488 for key , value in props .items ():
1483- item = self ._item_context (value , None if context else 0 )
1489+ item = self ._get_item_context (value , None if context else 0 )
14841490 if item is not None :
14851491 kw [key ] = item
14861492 return kw
@@ -1502,7 +1508,7 @@ def find(self, key, *, context=False):
15021508 Configurator.category
15031509 Configurator.fill
15041510 """
1505- return self ._item_context (key , None if context else 0 )
1511+ return self ._get_item_context (key , None if context else 0 )
15061512
15071513 def update (self , * args , ** kwargs ):
15081514 """
@@ -1586,7 +1592,7 @@ def _load_file(self, path):
15861592 with warnings .catch_warnings ():
15871593 warnings .simplefilter ('error' , warnings .ProplotWarning )
15881594 try :
1589- ikw_proplot , ikw_matplotlib = self ._item_dicts (key , val )
1595+ ikw_proplot , ikw_matplotlib = self ._get_item_dicts (key , val )
15901596 except KeyError :
15911597 warnings ._warn_proplot (
15921598 f'Invalid rc key { key !r} on { message } .' , 'default'
@@ -1602,7 +1608,7 @@ def _load_file(self, path):
16021608 f'Outdated rc key { key !r} on { message } : { err } ' , 'default'
16031609 )
16041610 warnings .simplefilter ('ignore' , warnings .ProplotWarning )
1605- ikw_proplot , ikw_matplotlib = self ._item_dicts (key , val )
1611+ ikw_proplot , ikw_matplotlib = self ._get_item_dicts (key , val )
16061612 # Update the settings
16071613 kw_proplot .update (ikw_proplot )
16081614 kw_matplotlib .update (ikw_matplotlib )
0 commit comments