Talk Python acceptance run
August 2, 2026 · View on GitHub
The goal of this work is to run the real Talk Python application and its tests against TinyMongo, not merely to approximate its query list. The repository now contains two layers that make that handoff practical:
- Talk-Python-derived contracts run through TinyMongo's synchronous and asynchronous APIs against every supported embedded backend and real MongoDB.
scripts/run_pymongo_acceptance.pystarts an external pytest suite whilepymongo.MongoClientandpymongo.AsyncMongoClientare patched to use a selected TinyMongo backend.
Mike Kennedy has now run the second layer in the Talk Python repository against both MongoDB and TinyMongo SQLite. The remaining acceptance work is to rerun the focused follow-up cases, exercise the write-heavy admin and concurrency paths, and publish the complete dimensioned report.
Prepare the application environment
Use the Talk Python test environment so all of its application dependencies and configuration are available. Install the TinyMongo checkout and pytest into that environment:
python -m pip install -e "/path/to/tinymongo[all]" pytest
The runner activates the patch before pytest imports the application's test
modules. Existing from pymongo import AsyncMongoClient imports and client
construction therefore keep their normal call sites.
Establish the MongoDB reference
First configure Talk Python exactly as it is normally configured for its test MongoDB, then run the selected application suite without patching:
python /path/to/tinymongo/scripts/run_pymongo_acceptance.py \
--api async \
--backend mongodb \
--suite talkpython-app \
--junitxml talkpython-async-mongodb.xml \
-- /path/to/talkpython/tests -q
--backend mongodb only adds report metadata; it deliberately leaves PyMongo
untouched. The application's normal environment variable or configuration must
point at the reference MongoDB.
Try the application with TinyMongo
Run the identical tests through an isolated in-memory database:
python /path/to/tinymongo/scripts/run_pymongo_acceptance.py \
--api async \
--backend memory \
--suite talkpython-app \
--junitxml talkpython-async-memory.xml \
-- /path/to/talkpython/tests -q
Then repeat with SQLite to exercise a durable backend:
python /path/to/tinymongo/scripts/run_pymongo_acceptance.py \
--api async \
--backend sqlite \
--folder .talkpython-tinymongo \
--suite talkpython-app \
--junitxml talkpython-async-sqlite.xml \
-- /path/to/talkpython/tests -q
The patch affects process-global PyMongo client classes for the duration of the pytest session. Run these acceptance commands as separate processes rather than inside an already-running application server.
Generate the application report
Combine the three JUnit files into one deterministic baseline:
python /path/to/tinymongo/scripts/generate_compatibility_report.py \
talkpython-async-mongodb.xml \
talkpython-async-memory.xml \
talkpython-async-sqlite.xml \
--apis async \
--backends memory,sqlite,mongodb \
--json-output talkpython-compatibility.json \
--markdown-output talkpython-compatibility.md
The report is publishable only when every expected target cell was executed, the matching MongoDB reference behavior passed, and no result is unattributed. A partial run is still rendered, but it is labeled incomplete.
Application result and rerun gate
Mike Kennedy's first real Talk Python pass reached the asynchronous application initializer on SQLite, opened all four database handles, and accepted the index declarations for all 16 collections. It reduced the first blocking differences to reusable contracts:
- datetimes and ObjectIds must sort instead of silently retaining insertion order;
- BinData must sort by length, subtype, and bytes;
Binary,bytes, andbytearraymust cross the JSON persistence boundary; generic subtype-0 values must compare like native bytes while other subtypes remain distinct;insert_many()must distinguish duplicate-key partial failures from client-side encoding failures; and- synchronous and asynchronous code must preserve the same behavior across memory, JSON, SQLite, DuckDB, and Parquet.
After those fixes, Mike migrated all 81,017 source documents with zero
rejections and ran the real application suite through this repository's
acceptance runner. After the final follow-up in #143, MongoDB and TinyMongo
SQLite both passed all 597 tests; all nine application surfaces and all 21
admin-write checks passed. The public site rendered from TinyMongo without
MongoDB running. The final recorded TinyMongo baseline was master at
07e9b40, Python 3.14.6, PyMongo 4.17, and the SQLite backend. A fresh-memory
run initially exposed four sitemap failures, which Mike confirmed and fixed as
empty-data assumptions in the application rather than TinyMongo differences.
The Mongo-compatible behaviors also run through TinyMongo's shared
synchronous/asynchronous matrix and real MongoDB contracts. TinyMongo's
stronger whole-input serialization preflight is covered locally because
PyMongo may split a very large input across wire batches. Before publishing the
final dimensioned report, record the exact Talk Python commit, selected test
inventory, and configuration for each rerun. The runner's --api value labels
results; the application configuration must actually exercise the
corresponding client path.
Follow-up compatibility fixes
Mike's next focused pass identified three more PyMongo-facing differences:
- omitted
_idvalues needed to be nativeObjectIdinstances so the application could reconstruct them from their string form; $ne: Noneand$ninlists containingNoneneeded to exclude missing fields; and- unsupported document values needed to raise
InvalidDocumentinstead of a bare serializationTypeError.
These cases now run through the shared synchronous/asynchronous contract
matrix. TinyMongo creates native automatic IDs when optional BSON support is
available, while dependency-free writes and the explicit generate_id()
helper retain UUID strings. Invalid-document failures happen before storage,
retain the rejected document and nested path context, and are catchable through
both BSON's InvalidDocument and PyMongoError when PyMongo is installed.
Mike reran these cases unchanged against 07e9b40; all passed in the focused
reproductions and the real Talk Python write paths. The main application goal
is complete with no known correctness defect in Talk Python's TinyMongo path.
Mike's separate TinyMongo agent reference should now be updated against the
v1.3.0 tag, including the Binary codec, BSON-aware _id identity,
insert_many() partial failures,
bounded sort diagnostics, exact $unset, BSON-aware CLI, dotted child
collections, native automatic ObjectId values, null-negation behavior, and
contextual InvalidDocument errors. It should also describe the structured
query, update-operator, aggregation, and BSON-type capabilities plus the
expanded $rename, $min, $max, and $pop update subset. Also correct the
stale list-only
insert_many() signature and defaults, BulkWriteError details, blanket
session claim, conditional AsyncMongoClient patch/import caveat,
numeric-versus-bool identity wording, explicit null _id handling, _default
collection filtering, current error/result shapes, and bytearray
normalization. It should call PyMongo an optional runtime dependency—not a core
dependency—for ObjectId and nonzero Binary values, patching, and conditional
exception inheritance.
The same guide update should correct constructor and sync-laziness wording,
document validation as a no-op, empty-array and sort-error details,
backend-specific locking and durability, the full object-storage environment
table, portable capability and duplicate-error examples, and the fact that CLI
migration does not copy source index metadata.
Mike's final TM-019/TM-030 fidelity pass is also captured as shared contracts.
PyMongo-shaped synchronous and asynchronous clients recursively honor
document_class, tz_aware, and tzinfo; persisted datetimes now use BSON's
signed UTC millisecond representation. The option-name allowlist follows the
installed PyMongo validator catalog when available, and malformed operators
inside $elemMatch report MongoDB error code 2 without disguising valid but
unsupported predicates as malformed input.
Handling failures
For each difference found in the real application:
- reduce the behavior to the smallest document, operation, and assertion;
- add it to
tests/contractsfor both sync and async APIs; - compare the same case with real MongoDB;
- link the temporary expected difference to the relevant roadmap issue;
- fix TinyMongo or document the intentional difference; and
- rerun the same Talk Python test before updating the published baseline.
The first application pass should prioritize whether Talk Python starts, creates its indexes, completes its service-layer tests, and shuts down cleanly. Broader backend coverage can follow after memory and SQLite have a trustworthy baseline.