From cd2b449856442483dadd31e6b0198e0f0ef04135 Mon Sep 17 00:00:00 2001 From: Thor Whalen <1906276+thorwhalen@users.noreply.github.com> Date: Tue, 22 Sep 2026 14:08:22 +0000 Subject: [PATCH] fix: ChromaUris was shadowed by a second class writing a non-field base.py defined `ChromaUris` twice; the second (codec field "metadata", which is not a chromadb kwarg) replaced the first, so every ChromaUris write/append raised TypeError. #3's test covered "ChromaUris" only through a fake that accepts any kwarg, so it passed. The second class is now `ChromaMetadatas` on the real "metadatas" field, with no `append` since chromadb refuses an upsert that has metadata but no documents. Co-Authored-By: Claude Opus 5 --- chromadol/base.py | 19 ++++++++++++----- chromadol/tests/test_appendable.py | 33 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/chromadol/base.py b/chromadol/base.py index 53495b2..cac11bb 100644 --- a/chromadol/base.py +++ b/chromadol/base.py @@ -133,13 +133,22 @@ class ChromaDocuments(ChromaCollection): @appendable(item2kv=uuid_key) @ValueCodecs.single_nested_value("uris") class ChromaUris(ChromaCollection): - """ChromaCollection but reading and writing only the 'uris' field.""" + """ChromaCollection but reading and writing only the 'uris' field. + Writing uris needs a collection created with a ``data_loader`` (see + ``chromadol.data_loaders``); ``chromadb`` refuses uris without one. + """ -@appendable(item2kv=uuid_key) -@ValueCodecs.single_nested_value("metadata") -class ChromaUris(ChromaCollection): - """ChromaCollection but reading and writing only the 'uris' field.""" + +@ValueCodecs.single_nested_value("metadatas") +class ChromaMetadatas(ChromaCollection): + """ChromaCollection but reading and writing only the 'metadatas' field. + + Mainly a read view: ``chromadb`` refuses an ``upsert`` that carries neither + documents nor images, so writing metadata alone raises (that is also why this + one has no ``append``). Write metadata with the documents, through + ``ChromaCollection`` or ``AppendableChromaCollection``. + """ class ChromaClient(MutableMapping): diff --git a/chromadol/tests/test_appendable.py b/chromadol/tests/test_appendable.py index 036ffa6..891b439 100644 --- a/chromadol/tests/test_appendable.py +++ b/chromadol/tests/test_appendable.py @@ -14,6 +14,7 @@ AppendableChromaCollection, ChromaCollection, ChromaDocuments, + ChromaMetadatas, ChromaUris, ) @@ -100,3 +101,35 @@ def test_appendable_chroma_collection_appends_raw_chromadb_kwargs(tmp_path): record = raw[key] assert record["documents"] == ["raw document"] assert record["metadatas"] == [{"author": "me"}] + + +@pytest.mark.parametrize( + "store_cls, field", + [ + (ChromaDocuments, "documents"), + (ChromaUris, "uris"), + (ChromaMetadatas, "metadatas"), + ], + ids=lambda x: getattr(x, "__name__", x), +) +def test_single_field_stores_write_their_own_chromadb_field(store_cls, field): + """Each single-field store must write the ``chromadb`` kwarg it is named for. + + ``ChromaUris`` used to be silently redefined by a second class (field + ``"metadata"``, not even a ``chromadb`` kwarg), so every write raised + ``TypeError: upsert() got an unexpected keyword argument 'metadata'``. + """ + collection = _RecordingCollection() + store_cls(collection)["a_key"] = "a value" + ((_ids, kwargs),) = collection.upserts + assert list(kwargs) == [field] + + +def test_chroma_metadatas_reads_the_metadatas_field(tmp_path): + client = chromadb.PersistentClient(str(tmp_path / "metas")) + collection = client.create_collection("metas", get_or_create=True) + ChromaCollection(collection)["k"] = { + "documents": "doc", + "metadatas": {"author": "me"}, + } + assert ChromaMetadatas(collection)["k"] == [{"author": "me"}]