Skip to main content

inmemory-datastore-stub

PyPI Python License CI Ruff

An in-memory Google Cloud Datastore stub for unit-testing python-ndb code — no emulator, no Java, no network, no gcloud component to install.

It implements the Datastore RPC surface in pure Python, so your tests run at in-process speed.

Why this package exists

This is a maintained fork of InMemoryCloudDatastoreStub by Phil Lopreiato, which has been unmaintained since January 2021 and only works with google-cloud-datastore 1.x. On the 2.x libraries it fails outright:

  • google.cloud.datastore_v1.proto was removed in datastore 2.x, so importing the original raises ModuleNotFoundError
  • datastore 2.x wraps every message in proto-plus, which does not expose the protobuf-only API the stub relies on (WhichOneof, HasField, CopyFrom, SerializeToString)
  • ndb 2.x calls the RPC methods by snake_case name (lookup, commit, run_query, …) while the original only exposes the 1.x CamelCase names
  • ndb 2.x expects a database attribute on the client
  • allocate_ids was never implemented

This fork fixes all of the above and is tested on Python 3.10–3.14.

Install

pip install inmemory-datastore-stub

Usage

The simplest form — use the stub-backed client directly:

from google.cloud import ndb
from inmemory_datastore_stub import Client


class Movie(ndb.Model):
    title = ndb.StringProperty()


def test_movies():
    with Client().context():
        Movie(title="Roman Holiday").put()
        assert Movie.query().count() == 1

As a pytest fixture:

import pytest
from inmemory_datastore_stub import Client


@pytest.fixture
def ndb_context():
    with Client().context():
        yield

If the code under test constructs its own ndb.Client(), patch it globally:

from inmemory_datastore_stub import patch_ndb

with patch_ndb():
    import myapp  # myapp calls ndb.Client() at import time

    myapp.run()

patch_ndb() restores the original ndb.Client on exit.

Catching bugs the stub would otherwise hide

Two behaviours of real Datastore make code fail in production that passes against a naive in-memory stub. Both are reproduced here, and both are opt-in so they never break an existing suite.

Eventual consistency

Non-ancestor queries in Datastore do not see writes immediately. Turn that on and the stub holds fresh writes back until you call catch_up():

client = Client(eventual_consistency=True)

with client.context():
    Movie(title="fresh").put()

    assert Movie.query().fetch() == []  # non-ancestor query lags, as in production
    assert movie.key.get().title == "fresh"  # key lookups are strongly consistent

    client.catch_up()
    assert len(Movie.query().fetch()) == 1

Ancestor queries and key lookups stay strongly consistent, matching Datastore.

Composite index validation

Datastore refuses any query whose composite index is not declared in index.yaml. Point the stub at yours and it refuses them too — with the same index suggestion Datastore gives you, ready to paste:

client = Client(index_yaml="index.yaml")
NoMatchingIndexError: no matching index found. recommended index is:
indexes:
- kind: Movie
  properties:
  - name: genre
  - name: title

Needs PyYAML: pip install 'inmemory-datastore-stub[indexes]'.

What is supported

put, get, delete, put_multi/get_multi/delete_multi, get_or_insert, allocate_ids, transactions, and ancestor queries.

Queries: equality, inequality, !=, IN, NOT_IN, OR, repeated properties, StructuredProperty and ComputedProperty, ordering by several properties in either direction, offset/limit, count, cursors and fetch_page, projection and keys-only queries, and GQL.

Not reproduced: index build state, query planning details, and Datastore's own size and rate limits. For those, use the official Datastore emulator.

License

MIT — see LICENSE. Original work © 2020 Phil Lopreiato; modifications © 2026 Stepan Shamaiev.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

inmemory_datastore_stub-1.0.0.tar.gz (66.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

inmemory_datastore_stub-1.0.0-py3-none-any.whl (17.1 kB view details)

Uploaded Python 3

File details

Details for the file inmemory_datastore_stub-1.0.0.tar.gz.

File metadata

  • Download URL: inmemory_datastore_stub-1.0.0.tar.gz
  • Upload date:
  • Size: 66.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for inmemory_datastore_stub-1.0.0.tar.gz
Algorithm Hash digest
SHA256 5aa79f3cae1f48b257ffdedd77ca4baa829557e6d6bb22dfe9f5f637bb2a8449
MD5 7ff5e47585c76d3fe1243dc2d7e6117c
BLAKE2b-256 65eb05b2a5f7b3885d5e9875d94461a0d860e3e986152332a03096ebb03d5149

See more details on using hashes here.

Provenance

The following attestation bundles were made for inmemory_datastore_stub-1.0.0.tar.gz:

Publisher: publish.yml on skippdot/inmemory-datastore-stub

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inmemory_datastore_stub-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for inmemory_datastore_stub-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0ab7456d6a22a3b77ee1592df47d860981de086523210077707ef36307f1a5e7
MD5 6167bd2fce2d0dd337f690a154109733
BLAKE2b-256 f70fdddd809173ae9f7e9f0fda8c5f99a27d12cb472b0f0d807816543da9ab44

See more details on using hashes here.

Provenance

The following attestation bundles were made for inmemory_datastore_stub-1.0.0-py3-none-any.whl:

Publisher: publish.yml on skippdot/inmemory-datastore-stub

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.1.0

2 files

This release

1.0.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page