Source code for oasislmf.cli.clearcache

import os
import subprocess
import sys
from pathlib import Path

from .command import OasisBaseCommand

# Deletion runs in a subprocess with NUMBA_DISABLE_JIT=1 because Numba
# re-creates cache files instantly if JIT is active in the same process

_CACHE_GLOBS = ('*.nbi', '*.nbc')

_DELETE_SCRIPT = """\
import sys
from pathlib import Path

roots = sys.argv[1:]
files = [f for r in roots for ext in {globs!r} for f in Path(r).rglob(ext)]
removed = failed = 0
for f in files:
    try:
        f.unlink()
        removed += 1
    except OSError as e:
        print(f'WARNING: {{e}}', flush=True)
        failed += 1
print(removed, failed, flush=True)
""".format(globs=_CACHE_GLOBS)


def _find_cache_files(roots):
    return [f for r in roots for ext in _CACHE_GLOBS for f in r.rglob(ext)]


[docs] class ClearCacheCmd(OasisBaseCommand): """Deletes all Numba cache files."""
[docs] def add_args(self, parser): super().add_args(parser) parser.add_argument( '--list', action='store_true', help='List Numba cache files without deleting them', )
[docs] def action(self, args): pkg_root = Path(__file__).resolve().parents[1] roots = [pkg_root] cache_dir = os.environ.get('NUMBA_CACHE_DIR') if cache_dir: roots.append(Path(cache_dir)) if args.list: cache_files = _find_cache_files(roots) if not cache_files: self.logger.info('No Numba cache files found.') return for f in sorted(cache_files): self.logger.info(f' {f}') self.logger.info(f'Numba cache files found: {len(cache_files)}') return env = {**os.environ, 'NUMBA_DISABLE_JIT': '1'} result = subprocess.run( [sys.executable, '-c', _DELETE_SCRIPT, *[str(r) for r in roots]], env=env, capture_output=True, text=True, ) if result.returncode != 0: self.logger.error(result.stderr) return 1 for line in result.stdout.splitlines(): if line.startswith('WARNING:'): self.logger.warning(line[len('WARNING:'):].strip()) continue removed, failed = map(int, line.split()) msg = f'Numba cache files removed: {removed}' if failed: msg += f'\nNumba cache files unable to be removed: {failed}' self.logger.info(msg)