Skip to content

Allow independent stores in MemoryFileSystem - #2137

Merged
martindurant merged 3 commits into
fsspec:masterfrom
aprylewu:fix/memory-independent-stores
Sep 15, 2026
Merged

martindurant merged 3 commits into
fsspec:masterfrom
aprylewu:fix/memory-independent-stores

Conversation

@aprylewu

@aprylewu aprylewu commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Memory filesystem instances always share their files and directories, even when callers bypass the instance cache. Add global_store=False for instance-local storage, so callers can create in-memory workspaces with overlapping paths.

Use global_store=False, skip_instance_cache=True to create a fresh independent workspace on each call. Normal instance caching still applies when the cache option is omitted. Each private instance owns its files and empty directories and has a distinct filesystem token. Both options also work through fsspec configuration.

Pickling a private filesystem copies its contents into a fresh instance, including when the source was cached. File objects point back to the restored filesystem through pickle's memo. Default construction preserves the global store, instance reuse, and transaction behavior, including writes through fsspec.open() and fsspec.get_mapper(). This uses the existing cache machinery without a new metaclass.

Closes #1904; follows the abandoned #1905. The discussion in #1906 suggested disabling MemoryFS caching altogether; keeping normal caching preserves the transaction association of the top-level helpers.

Validation on macOS / Python 3.13.5:

  • Eight related test modules: 563 passed, 118 skipped, 2 xfailed, including 51 memory tests.
  • An independent agent reviewed the revision and ran 31 additional checks covering cache options, configuration/environment overrides, default and private transactions, pickle protocols 2–5, deepcopy, and restored file back-references.
  • Ruff 0.14.3, formatting, codespell 2.4.0, and git diff --check passed.

The full Docker/FUSE/downstream suite and documentation build were not run. JSON serialization still records constructor options; it does not copy memory contents.

AI assistance: OpenAI Codex assisted with the implementation, tests, and this description. The validation results above are from local execution.

Signed-off-by: Mingyang Wu <129849514+aprylewu@users.noreply.github.com>
Signed-off-by: Mingyang Wu <129849514+aprylewu@users.noreply.github.com>

@martindurant martindurant left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because MemoryFS doesn't take any arguments, users were previously getting not just the same underlying storage, but the same instance back every time (unless they knew what they were doing).

The code here introduces the only subclass of _Cached so far, and I think we need to be really careful with metaclasses - is there no simpler way? Users can already pass skip_instance_cache= themselves after all.

Comment thread fsspec/implementations/tests/test_memory.py Outdated
Comment thread fsspec/implementations/tests/test_memory.py Outdated
Comment thread fsspec/implementations/tests/test_memory.py
Signed-off-by: Mingyang Wu <aprylewu@gmail.com>

Assisted-by: OpenAI Codex
@aprylewu

Copy link
Copy Markdown
Contributor Author

Thanks, the metaclass was unnecessary. Removed it in de740c9; global_store=False now selects instance-local storage while callers use the existing skip_instance_cache=True option when they need a fresh instance. The docs and config tests follow that behavior.

One detail needed care after removing it: unpickling a private filesystem must bypass the cache so it cannot overwrite the original cached instance. The reducer now does that explicitly. A regression test takes a snapshot, modifies the source, then checks that loading the snapshot leaves the source untouched.

Also applied the two identity assertions and explained the file back-reference inline. The eight related test modules passed locally (563 passed, 118 skipped, 2 xfailed), as did Ruff and codespell. An independent agent reviewed the revision and passed 31 additional cache/serialization/transaction checks.

@martindurant
martindurant merged commit d510b90 into fsspec:master Sep 15, 2026
20 of 22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

create multiple separate memory filesystems

2 participants