@@ -213,16 +213,28 @@ def _is_writable_dir(p):
213213 p is a string pointing to a putative writable dir -- return True p
214214 is such a string, else False
215215 """
216- try : p + '' # test is string like
217- except TypeError : return False
216+ try :
217+ p + '' # test is string like
218+ except TypeError :
219+ return False
220+
221+ # Test whether the operating system thinks it's a writable directory.
222+ # Note that this check is necessary on Google App Engine, because the
223+ # subsequent check will succeed even though p may not be writable.
224+ if not os .access (p , os .W_OK ) or not os .path .isdir (p ):
225+ return False
226+
227+ # Also test that it is actually possible to write to a file here.
218228 try :
219229 t = tempfile .TemporaryFile (dir = p )
220230 try :
221231 t .write (ascii ('1' ))
222232 finally :
223233 t .close ()
224- except OSError : return False
225- else : return True
234+ except OSError :
235+ return False
236+
237+ return True
226238
227239class Verbose :
228240 """
@@ -475,38 +487,42 @@ def checkdep_usetex(s):
475487
476488def _get_home ():
477489 """Find user's home directory if possible.
478- Otherwise raise error .
490+ Otherwise, returns None .
479491
480- :see: http://mail.python.org/pipermail/python-list/2005-February/263921 .html
492+ :see: http://mail.python.org/pipermail/python-list/2005-February/325395 .html
481493 """
482- path = ''
483494 try :
484- path = os .path .expanduser ("~" )
485- except :
495+ path = os .path .expanduser ("~" )
496+ except ImportError :
497+ # This happens on Google App Engine (pwd module is not present).
486498 pass
487- if not os .path .isdir (path ):
488- for evar in ('HOME' , 'USERPROFILE' , 'TMP' ):
489- try :
490- path = os .environ [evar ]
491- if os .path .isdir (path ):
492- break
493- except : pass
494- if path :
495- return path
496499 else :
497- raise RuntimeError ('please define environment variable $HOME' )
500+ if os .path .isdir (path ):
501+ return path
502+ for evar in ('HOME' , 'USERPROFILE' , 'TMP' ):
503+ path = os .environ .get (evar )
504+ if path is not None and os .path .isdir (path ):
505+ return path
506+ return None
498507
499508
500509def _create_tmp_config_dir ():
501510 """
502511 If the config directory can not be created, create a temporary
503512 directory.
513+
514+ Returns None if a writable temporary directory could not be created.
504515 """
505516 import getpass
506517 import tempfile
507518
508- tempdir = os .path .join (
509- tempfile .gettempdir (), 'matplotlib-%s' % getpass .getuser ())
519+ try :
520+ tempdir = tempfile .gettempdir ()
521+ except NotImplementedError :
522+ # Some restricted platforms (such as Google App Engine) do not provide
523+ # gettempdir.
524+ return None
525+ tempdir = os .path .join (tempdir , 'matplotlib-%s' % getpass .getuser ())
510526 os .environ ['MPLCONFIGDIR' ] = tempdir
511527
512528 return tempdir
@@ -518,35 +534,42 @@ def _get_configdir():
518534 """
519535 Return the string representing the configuration directory.
520536
521- Default is HOME/.matplotlib. You can override this with the
522- MPLCONFIGDIR environment variable. If the default is not
523- writable, and MPLCONFIGDIR is not set, then
524- tempfile.gettempdir() is used to provide a directory in
525- which a matplotlib subdirectory is created as the configuration
526- directory.
537+ The directory is chosen as follows:
538+
539+ 1. If the MPLCONFIGDIR environment variable is supplied, choose that. Else,
540+ choose the '.matplotlib' subdirectory of the user's home directory (and
541+ create it if necessary).
542+ 2. If the chosen directory exists and is writable, use that as the
543+ configuration directory.
544+ 3. If possible, create a temporary directory, and use it as the
545+ configuration directory.
546+ 4. A writable directory could not be found or created; return None.
527547 """
528548
529549 configdir = os .environ .get ('MPLCONFIGDIR' )
530550 if configdir is not None :
531551 if not os .path .exists (configdir ):
532- os . makedirs (configdir )
552+ mkdirs (configdir )
533553 if not _is_writable_dir (configdir ):
534554 return _create_tmp_config_dir ()
535555 return configdir
536556
537557 h = get_home ()
538- p = os .path .join (get_home (), '.matplotlib' )
558+ if h is not None :
559+ p = os .path .join (h , '.matplotlib' )
539560
540- if os .path .exists (p ):
541- if not _is_writable_dir (p ):
542- return _create_tmp_config_dir ()
543- else :
544- if not _is_writable_dir (h ):
545- return _create_tmp_config_dir ()
546- from matplotlib .cbook import mkdirs
547- mkdirs (p )
561+ if os .path .exists (p ):
562+ if not _is_writable_dir (p ):
563+ return _create_tmp_config_dir ()
564+ else :
565+ if not _is_writable_dir (h ):
566+ return _create_tmp_config_dir ()
567+ from matplotlib .cbook import mkdirs
568+ mkdirs (p )
548569
549- return p
570+ return p
571+
572+ return _create_tmp_config_dir ()
550573get_configdir = verbose .wrap ('CONFIGDIR=%s' , _get_configdir , always = False )
551574
552575
@@ -636,27 +659,39 @@ def matplotlib_fname():
636659
637660 """
638661
639- oldname = os .path .join ( os .getcwd (), '.matplotlibrc' )
662+ oldname = os .path .join (os .getcwd (), '.matplotlibrc' )
640663 if os .path .exists (oldname ):
641- print ("""\
642- WARNING: Old rc filename ".matplotlibrc" found in working dir
643- and and renamed to new default rc file name "matplotlibrc"
644- (no leading"dot"). """ , file = sys .stderr )
645- shutil .move ('.matplotlibrc' , 'matplotlibrc' )
664+ try :
665+ shutil .move ('.matplotlibrc' , 'matplotlibrc' )
666+ except IOError as e :
667+ warnings .warn ('File could not be renamed: %s' % e )
668+ else :
669+ warnings .warn ("""\
670+ Old rc filename ".matplotlibrc" found in working dir and and renamed to new
671+ default rc file name "matplotlibrc" (no leading ".").""" )
646672
647673 home = get_home ()
648- oldname = os .path .join ( home , '.matplotlibrc' )
649- if os .path .exists (oldname ):
650- configdir = get_configdir ()
651- newname = os .path .join (configdir , 'matplotlibrc' )
652- print ("""\
653- WARNING: Old rc filename "%s" found and renamed to
654- new default rc file name "%s".""" % (oldname , newname ), file = sys .stderr )
655-
656- shutil .move (oldname , newname )
657-
674+ configdir = get_configdir ()
675+ if home :
676+ oldname = os .path .join (home , '.matplotlibrc' )
677+ if os .path .exists (oldname ):
678+ if configdir is not None :
679+ newname = os .path .join (configdir , 'matplotlibrc' )
680+
681+ try :
682+ shutil .move (oldname , newname )
683+ except IOError as e :
684+ warnings .warn ('File could not be renamed: %s' % e )
685+ else :
686+ warnings .warn ("""\
687+ Old rc filename "%s" found and renamed to new default rc file name "%s"."""
688+ % (oldname , newname ))
689+ else :
690+ warnings .warn ("""\
691+ Could not rename old rc file "%s": a suitable configuration directory could not
692+ be found.""" % oldname )
658693
659- fname = os .path .join ( os .getcwd (), 'matplotlibrc' )
694+ fname = os .path .join (os .getcwd (), 'matplotlibrc' )
660695 if os .path .exists (fname ): return fname
661696
662697 if 'MATPLOTLIBRC' in os .environ :
@@ -666,9 +701,10 @@ def matplotlib_fname():
666701 if os .path .exists (fname ):
667702 return fname
668703
669- fname = os .path .join (get_configdir (), 'matplotlibrc' )
670- if os .path .exists (fname ): return fname
671-
704+ if configdir is not None :
705+ fname = os .path .join (configdir , 'matplotlibrc' )
706+ if os .path .exists (fname ):
707+ return fname
672708
673709 path = get_data_path () # guaranteed to exist or raise
674710 fname = os .path .join (path , 'matplotlibrc' )
0 commit comments