| 307 | def _cached_loader(func, name=name): |
| 308 | # type: (DecoratorCallable, str) -> DecoratorCallable |
| 309 | def load(filename=None): |
| 310 | # type: (Optional[str]) -> Any |
| 311 | cache_id = hashlib.sha256((filename or "").encode()).hexdigest() |
| 312 | if cachepath.exists(): |
| 313 | try: |
| 314 | with cachepath.open("rb") as fd: |
| 315 | data = pickle.load(fd) |
| 316 | if data["id"] == cache_id: |
| 317 | return data["content"] |
| 318 | except Exception as ex: |
| 319 | log_loading.info( |
| 320 | "Couldn't load cache from %s: %s" % ( |
| 321 | str(cachepath), |
| 322 | str(ex), |
| 323 | ) |
| 324 | ) |
| 325 | cachepath.unlink(missing_ok=True) |
| 326 | # Cache does not exist or is invalid. |
| 327 | content = func(filename) |
| 328 | data = { |
| 329 | "content": content, |
| 330 | "id": cache_id, |
| 331 | } |
| 332 | try: |
| 333 | cachepath.parent.mkdir(parents=True, exist_ok=True) |
| 334 | with cachepath.open("wb") as fd: |
| 335 | pickle.dump(data, fd) |
| 336 | return content |
| 337 | except Exception as ex: |
| 338 | log_loading.info( |
| 339 | "Couldn't write cache into %s: %s" % ( |
| 340 | str(cachepath), |
| 341 | str(ex) |
| 342 | ) |
| 343 | ) |
| 344 | return content |
| 345 | return load # type: ignore |
| 346 | return _cached_loader |
| 347 | |