Skip to content

v5.8.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 23:18
· 33 commits to master since this release
22527b6

The package is now imported as diskcache_community, so it installs next to the upstream diskcache package instead of replacing it. The cache.db schema, the file layout, the serialization modes, the memoize key format and the persisted settings are unchanged, so a 5.6.3 process opens a directory written by 5.8.0 and the reverse. SafeDisk stays opt-in and gains an allowlist for your own classes, a process-wide default disk selects it for caches that libraries create, and caches can treat unreadable entries as missing.

Security

  • SafeDisk.with_types(*types, modules=()) returns a SafeDisk subclass whose allowlist adds the given classes, matched by identity, and every class defined in the named modules or below them. A module name may only reach a class defined in that module: a dotted name such as os.system, reached through a module that imports os, a class the module merely imports, a module and a dunder attribute are refused, and reading never imports a module, so a pickle cannot run a module's top-level code. numpy classes are refused (UNSAFE_MODULES), because numpy restores a dtype's flags from the pickle without checking them and a crafted array pickle can corrupt memory. Writes stay exact: a value outside the standard-library types is pickled and the names its pickle looks up are checked against the same allowlist, so a value the reader would refuse raises TypeError naming the class before anything is written. Calling with_types again adds to the allowlist, and a Cache, FanoutCache, Deque, Index or DjangoCache using the returned class pickles as before. The plain SafeDisk is unchanged (PR #23).

Docs

  • SECURITY.md describes what 5.8.0 adds for CVE-2025-69872 and links the steps (PR #28).
  • Two new pages: "Fix CVE-2025-69872 in diskcache" gives the steps to read caches with SafeDisk, including caches that libraries create, your own classes and entries already in the cache, and lists what any restricted disk has to cover; "Migrating from diskcache 5.6.3" covers the dependency, imports, Django settings, running next to upstream diskcache, the behaviour changes since 5.6.3 and going back. Both open the documentation and are linked from the README (PR #27).
  • A new benchmarks page, measured on 2026-10-12, compares diskcache-community with diskcache 5.6.3, memcached, Redis, lmdb, sqlitedict, shelve and the Django cache backends, with four charts. The scripts that produce it are in tests/benchmarks (driver.py runs the stores, report.py writes the page and charts from the JSON results). The 2019 pages from upstream stay as the old benchmarks, labelled as such and linked from the new page, and the README header, features and documentation list link to the new page (PR #26).
  • Shared links show a project card: a social preview image in .github/, and Open Graph tags on the documentation through sphinxext-opengraph (PR #21).
  • A logo: the README opens with a centered header (logo, name, tagline, links, badges) in the style of the other community forks, and the documentation shows the logo and a favicon (PR #20).
  • The README is rewritten in Markdown around install, usage and the fork story; the comparison tables move to a new comparisons page in the documentation, which gets its own landing page, and the 2016 testimonials are dropped (PR #19).
  • The documentation is published on Read the Docs at https://diskcache-community.readthedocs.io/, built from master on every push; the README links point there instead of at the .rst sources (PR #18).

Features

  • Disk.with_options(on_error='miss') returns a disk type, on any disk class including SafeDisk and the classes with_types returns, whose caches delete an entry they find but cannot read back (a corrupt or stale pickle, a refused type, a path outside the cache, an undecodable text file) and treat it as missing: get returns its default, cache[key] raises KeyError, pop, pull, peek and peekitem move on, and iteration skips unreadable keys. Index.items() and values() skip such entries too. The first such entry per cache is logged as a warning on the diskcache_community logger; a read-only cache does not delete it, and its peek and peekitem raise. A missing value file, MemoryError and RecursionError are never treated as unreadable. The default, on_error='raise', keeps raising as before, and the option is a class attribute that is never persisted (PR #25).
  • configure(disk) sets the disk type of every Cache, FanoutCache, Deque, Index and DjangoCache created afterwards without a disk, and default_disk() returns the type in effect. Without configure, the environment decides: DISKCACHE_DISK=safe selects SafeDisk, with DISKCACHE_SAFE_TYPES and DISKCACHE_SAFE_MODULES passed to SafeDisk.with_types, and DISKCACHE_DISK also takes default or the import path of a disk class. A disk passed explicitly always wins, so libraries that choose their own disk keep it; caches that already exist keep theirs, and nothing is persisted. The disk arguments now default to None, meaning that type (PR #24).

Packaging

  • Breaking: the package is imported as diskcache_community instead of diskcache, so it installs next to the upstream diskcache distribution without overwriting it, and a project can move to the fork while other dependencies still require diskcache. The public API, the cache.db schema, the file layout and the serialization are unchanged, so cache directories are shared with 5.6.3 in both directions. Django settings name diskcache_community.DjangoCache and diskcache_community.SafeDisk. The import-time warning about an upstream diskcache installed in the same environment is gone, and a CI job installs both distributions together, runs the golden tests in both directions and checks that uninstalling either leaves the other working (PR #22).
  • LICENSE now holds the full Apache License 2.0 text instead of the short boilerplate notice, so GitHub and package indexes detect the license; the copyright and fork notice stay in NOTICE (PR #21).