Skip to content

Commit 44aaa1b

Browse files
committed
Simplify caching of directories retrieval.
1 parent d0dea40 commit 44aaa1b

File tree

3 files changed

+50
-51
lines changed

3 files changed

+50
-51
lines changed

lib/matplotlib/__init__.py

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -386,27 +386,35 @@ def ge(self, level):
386386
verbose = Verbose()
387387

388388

389-
def _wrap(fmt, func, level=logging.DEBUG, always=True):
389+
def _logged_cached(fmt, func=None):
390390
"""
391-
return a callable function that wraps func and reports its
392-
output through logger
391+
Decorator that logs a function's return value, and memoizes that value.
393392
394-
if always is True, the report will occur on every function
395-
call; otherwise only on the first time the function is called
393+
After ::
394+
395+
@_logged_cached(fmt)
396+
def func(): ...
397+
398+
the first call to *func* will log its return value at the DEBUG level using
399+
%-format string *fmt*, and memoize it; later calls to *func* will directly
400+
return that value.
396401
"""
397-
assert callable(func)
398402

399-
def wrapper(*args, **kwargs):
400-
ret = func(*args, **kwargs)
403+
if func is None:
404+
return functools.partial(_logged_cached, fmt)
405+
406+
called = False
407+
ret = None
401408

402-
if (always or not wrapper._spoke):
403-
_log.log(level, fmt % ret)
404-
spoke = True
405-
if not wrapper._spoke:
406-
wrapper._spoke = spoke
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)
407416
return ret
408-
wrapper._spoke = False
409-
wrapper.__doc__ = func.__doc__
417+
410418
return wrapper
411419

412420

@@ -544,7 +552,8 @@ def checkdep_usetex(s):
544552
return flag
545553

546554

547-
def _get_home():
555+
@_logged_cached('$HOME=%s')
556+
def get_home():
548557
"""
549558
Return the user's home directory.
550559
@@ -555,8 +564,6 @@ def _get_home():
555564
except Exception:
556565
return None
557566

558-
get_home = _wrap('$HOME=%s', _get_home, always=False)
559-
560567

561568
def _create_tmp_config_dir():
562569
"""
@@ -575,7 +582,7 @@ def _get_xdg_config_dir():
575582
<http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_.
576583
"""
577584
return (os.environ.get('XDG_CONFIG_HOME')
578-
or (Path(get_home(), ".config")
585+
or (str(Path(get_home(), ".config"))
579586
if get_home()
580587
else None))
581588

@@ -587,21 +594,21 @@ def _get_xdg_cache_dir():
587594
<http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_.
588595
"""
589596
return (os.environ.get('XDG_CACHE_HOME')
590-
or (Path(get_home(), ".cache")
597+
or (str(Path(get_home(), ".cache"))
591598
if get_home()
592599
else None))
593600

594601

595602
def _get_config_or_cache_dir(xdg_base):
596603
configdir = os.environ.get('MPLCONFIGDIR')
597-
configdir = (
598-
Path(configdir).resolve()
599-
if configdir
600-
else Path(xdg_base, "matplotlib")
601-
if sys.platform.startswith(('linux', 'freebsd')) and xdg_base
602-
else Path(get_home(), ".matplotlib")
603-
if get_home()
604-
else None)
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
605612

606613
if configdir:
607614
try:
@@ -615,7 +622,9 @@ def _get_config_or_cache_dir(xdg_base):
615622
return _create_tmp_config_dir()
616623

617624

618-
def _get_configdir():
625+
626+
@_logged_cached('CONFIGDIR=%s')
627+
def get_configdir():
619628
"""
620629
Return the string representing the configuration directory.
621630
@@ -633,10 +642,9 @@ def _get_configdir():
633642
"""
634643
return _get_config_or_cache_dir(_get_xdg_config_dir())
635644

636-
get_configdir = _wrap('CONFIGDIR=%s', _get_configdir, always=False)
637-
638645

639-
def _get_cachedir():
646+
@_logged_cached('CACHEDIR=%s')
647+
def get_cachedir():
640648
"""
641649
Return the location of the cache directory.
642650
@@ -645,8 +653,6 @@ def _get_cachedir():
645653
"""
646654
return _get_config_or_cache_dir(_get_xdg_cache_dir())
647655

648-
get_cachedir = _wrap('CACHEDIR=%s', _get_cachedir, always=False)
649-
650656

651657
def _decode_filesystem_path(path):
652658
if not isinstance(path, str):
@@ -698,14 +704,12 @@ def _get_data_path():
698704
raise RuntimeError('Could not find the matplotlib data files')
699705

700706

701-
def _get_data_path_cached():
707+
@_logged_cached('matplotlib data path: %s')
708+
def get_data_path():
702709
if defaultParams['datapath'][0] is None:
703710
defaultParams['datapath'][0] = _get_data_path()
704711
return defaultParams['datapath'][0]
705712

706-
get_data_path = _wrap('matplotlib data path %s', _get_data_path_cached,
707-
always=False)
708-
709713

710714
def get_py2exe_datafiles():
711715
data_path = Path(get_data_path())
@@ -756,7 +760,7 @@ def gen_candidates():
756760
else:
757761
yield matplotlibrc
758762
yield os.path.join(matplotlibrc, 'matplotlibrc')
759-
yield os.path.join(_get_configdir(), 'matplotlibrc')
763+
yield os.path.join(get_configdir(), 'matplotlibrc')
760764
yield os.path.join(get_data_path(), 'matplotlibrc')
761765

762766
for fname in gen_candidates():

lib/matplotlib/style/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
BASE_LIBRARY_PATH = os.path.join(mpl.get_data_path(), 'stylelib')
2727
# Users may want multiple library paths, so store a list of paths.
28-
USER_LIBRARY_PATHS = [os.path.join(mpl._get_configdir(), 'stylelib')]
28+
USER_LIBRARY_PATHS = [os.path.join(mpl.get_configdir(), 'stylelib')]
2929
STYLE_EXTENSION = 'mplstyle'
3030
STYLE_FILE_PATTERN = re.compile(r'([\S]+).%s$' % STYLE_EXTENSION)
3131

lib/matplotlib/testing/compare.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818

1919
import matplotlib
2020
from matplotlib.testing.exceptions import ImageComparisonFailure
21-
from matplotlib import _png
22-
from matplotlib import _get_cachedir
23-
from matplotlib import cbook
21+
from matplotlib import _png, cbook
2422

2523
__all__ = ['compare_float', 'compare_images', 'comparable_formats']
2624

@@ -79,7 +77,7 @@ def compare_float(expected, actual, relTol=None, absTol=None):
7977

8078

8179
def get_cache_dir():
82-
cachedir = _get_cachedir()
80+
cachedir = matplotlib.get_cachedir()
8381
if cachedir is None:
8482
raise RuntimeError('Could not find a suitable configuration directory')
8583
cache_dir = os.path.join(cachedir, 'test_cache')
@@ -293,15 +291,12 @@ def comparable_formats():
293291

294292
def convert(filename, cache):
295293
"""
296-
Convert the named file into a png file. Returns the name of the
297-
created file.
294+
Convert the named file to png; return the name of the created file.
298295
299296
If *cache* is True, the result of the conversion is cached in
300-
`matplotlib._get_cachedir() + '/test_cache/'`. The caching is based
301-
on a hash of the exact contents of the input file. The is no limit
302-
on the size of the cache, so it may need to be manually cleared
303-
periodically.
304-
297+
`matplotlib.get_cachedir() + '/test_cache/'`. The caching is based on a
298+
hash of the exact contents of the input file. There is no limit on the
299+
size of the cache, so it may need to be manually cleared periodically.
305300
"""
306301
base, extension = filename.rsplit('.', 1)
307302
if extension not in converter:

0 commit comments

Comments
 (0)