@@ -217,13 +217,6 @@ def compare_versions(a, b):
217217 sys .argv = ['modpython' ]
218218
219219
220- def _is_writable_dir (p ):
221- """
222- p is a string pointing to a putative writable dir -- return True p
223- is such a string, else False
224- """
225- return os .access (p , os .W_OK ) and os .path .isdir (p )
226-
227220_verbose_msg = """\
228221 matplotlib.verbose is deprecated;
229222Command line argument --verbose-LEVEL is deprecated.
@@ -394,27 +387,34 @@ def ge(self, level):
394387 verbose = Verbose ()
395388
396389
397- def _wrap (fmt , func , level = logging . DEBUG , always = True ):
390+ def _logged_cached (fmt , func = None ):
398391 """
399- return a callable function that wraps func and reports its
400- output through logger
392+ Decorator that logs a function's return value, and memoizes that value.
401393
402- if always is True, the report will occur on every function
403- call; otherwise only on the first time the function is called
404- """
405- assert callable (func )
394+ After ::
406395
407- def wrapper ( * args , ** kwargs ):
408- ret = func (* args , ** kwargs )
396+ @_logged_cached(fmt)
397+ def func(): ...
409398
410- if (always or not wrapper ._spoke ):
411- _log .log (level , fmt % ret )
412- spoke = True
413- if not wrapper ._spoke :
414- wrapper ._spoke = spoke
399+ the first call to *func* will log its return value at the DEBUG level using
400+ %-format string *fmt*, and memoize it; later calls to *func* will directly
401+ return that value.
402+ """
403+ if func is None : # Return the actual decorator.
404+ return functools .partial (_logged_cached , fmt )
405+
406+ called = False
407+ ret = None
408+
409+ @functools .wraps (func )
410+ def wrapper ():
411+ nonlocal called , ret
412+ if not called :
413+ ret = func ()
414+ called = True
415+ _log .debug (fmt , ret )
415416 return ret
416- wrapper ._spoke = False
417- wrapper .__doc__ = func .__doc__
417+
418418 return wrapper
419419
420420
@@ -552,49 +552,39 @@ def checkdep_usetex(s):
552552 return flag
553553
554554
555- def _get_home ():
556- """Find user's home directory if possible.
557- Otherwise, returns None.
555+ @_logged_cached ('$HOME=%s' )
556+ def get_home ():
557+ """
558+ Return the user's home directory.
558559
559- :see:
560- http://mail.python.org/pipermail/python-list/2005-February/325395.html
560+ If the user's home directory cannot be found, return None.
561561 """
562- path = os .path .expanduser ("~" )
563- if os .path .isdir (path ):
564- return path
565- for evar in ('HOME' , 'USERPROFILE' , 'TMP' ):
566- path = os .environ .get (evar )
567- if path is not None and os .path .isdir (path ):
568- return path
569- return None
562+ try :
563+ return str (Path .home ())
564+ except Exception :
565+ return None
570566
571567
572568def _create_tmp_config_dir ():
573569 """
574- If the config directory can not be created, create a temporary
575- directory.
570+ If the config directory can not be created, create a temporary directory.
576571 """
577572 configdir = os .environ ['MPLCONFIGDIR' ] = (
578573 tempfile .mkdtemp (prefix = 'matplotlib-' ))
579574 atexit .register (shutil .rmtree , configdir )
580575 return configdir
581576
582577
583- get_home = _wrap ('$HOME=%s' , _get_home , always = False )
584-
585-
586578def _get_xdg_config_dir ():
587579 """
588580 Returns the XDG configuration directory, according to the `XDG
589581 base directory spec
590582 <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_.
591583 """
592- path = os .environ .get ('XDG_CONFIG_HOME' )
593- if path is None :
594- path = get_home ()
595- if path is not None :
596- path = os .path .join (path , '.config' )
597- return path
584+ return (os .environ .get ('XDG_CONFIG_HOME' )
585+ or (str (Path (get_home (), ".config" ))
586+ if get_home ()
587+ else None ))
598588
599589
600590def _get_xdg_cache_dir ():
@@ -603,60 +593,46 @@ def _get_xdg_cache_dir():
603593 base directory spec
604594 <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_.
605595 """
606- path = os .environ .get ('XDG_CACHE_HOME' )
607- if path is None :
608- path = get_home ()
609- if path is not None :
610- path = os .path .join (path , '.cache' )
611- return path
596+ return (os .environ .get ('XDG_CACHE_HOME' )
597+ or (str (Path (get_home (), ".cache" ))
598+ if get_home ()
599+ else None ))
612600
613601
614602def _get_config_or_cache_dir (xdg_base ):
615603 configdir = os .environ .get ('MPLCONFIGDIR' )
616- if configdir is not None :
617- configdir = os .path .abspath (configdir )
618- Path (configdir ).mkdir (parents = True , exist_ok = True )
619- if not _is_writable_dir (configdir ):
620- return _create_tmp_config_dir ()
621- return configdir
622-
623- p = None
624- h = get_home ()
625- if h is not None :
626- p = os .path .join (h , '.matplotlib' )
627- if sys .platform .startswith (('linux' , 'freebsd' )):
628- p = None
629- if xdg_base is not None :
630- p = os .path .join (xdg_base , 'matplotlib' )
631-
632- if p is not None :
633- if os .path .exists (p ):
634- if _is_writable_dir (p ):
635- return p
604+ if configdir :
605+ configdir = Path (configdir ).resolve ()
606+ elif sys .platform .startswith (('linux' , 'freebsd' )) and xdg_base :
607+ configdir = Path (xdg_base , "matplotlib" )
608+ elif get_home ():
609+ configdir = Path (get_home (), ".matplotlib" )
610+ else :
611+ configdir = None
612+
613+ if configdir :
614+ try :
615+ configdir .mkdir (parents = True , exist_ok = True )
616+ except OSError :
617+ pass
636618 else :
637- try :
638- Path (p ).mkdir (parents = True , exist_ok = True )
639- except OSError :
640- pass
641- else :
642- return p
619+ if os .access (str (configdir ), os .W_OK ) and configdir .is_dir ():
620+ return str (configdir )
643621
644622 return _create_tmp_config_dir ()
645623
646624
647- def _get_configdir ():
625+ @_logged_cached ('CONFIGDIR=%s' )
626+ def get_configdir ():
648627 """
649628 Return the string representing the configuration directory.
650629
651630 The directory is chosen as follows:
652631
653632 1. If the MPLCONFIGDIR environment variable is supplied, choose that.
654-
655633 2a. On Linux, follow the XDG specification and look first in
656634 `$XDG_CONFIG_HOME`, if defined, or `$HOME/.config`.
657-
658635 2b. On other platforms, choose `$HOME/.matplotlib`.
659-
660636 3. If the chosen directory exists and is writable, use that as the
661637 configuration directory.
662638 4. If possible, create a temporary directory, and use it as the
@@ -665,10 +641,9 @@ def _get_configdir():
665641 """
666642 return _get_config_or_cache_dir (_get_xdg_config_dir ())
667643
668- get_configdir = _wrap ('CONFIGDIR=%s' , _get_configdir , always = False )
669644
670-
671- def _get_cachedir ():
645+ @ _logged_cached ( 'CACHEDIR=%s' )
646+ def get_cachedir ():
672647 """
673648 Return the location of the cache directory.
674649
@@ -677,8 +652,6 @@ def _get_cachedir():
677652 """
678653 return _get_config_or_cache_dir (_get_xdg_cache_dir ())
679654
680- get_cachedir = _wrap ('CACHEDIR=%s' , _get_cachedir , always = False )
681-
682655
683656def _decode_filesystem_path (path ):
684657 if not isinstance (path , str ):
@@ -730,14 +703,12 @@ def _get_data_path():
730703 raise RuntimeError ('Could not find the matplotlib data files' )
731704
732705
733- def _get_data_path_cached ():
706+ @_logged_cached ('matplotlib data path: %s' )
707+ def get_data_path ():
734708 if defaultParams ['datapath' ][0 ] is None :
735709 defaultParams ['datapath' ][0 ] = _get_data_path ()
736710 return defaultParams ['datapath' ][0 ]
737711
738- get_data_path = _wrap ('matplotlib data path %s' , _get_data_path_cached ,
739- always = False )
740-
741712
742713def get_py2exe_datafiles ():
743714 data_path = Path (get_data_path ())
@@ -788,7 +759,7 @@ def gen_candidates():
788759 else :
789760 yield matplotlibrc
790761 yield os .path .join (matplotlibrc , 'matplotlibrc' )
791- yield os .path .join (_get_configdir (), 'matplotlibrc' )
762+ yield os .path .join (get_configdir (), 'matplotlibrc' )
792763 yield os .path .join (get_data_path (), 'matplotlibrc' )
793764
794765 for fname in gen_candidates ():
0 commit comments