· python til

Python: TypeError: Instance and class checks can only be used with @runtime_checkable protocols

I’ve been playing around with ChromaDB and I wanted to programatically get a list of the embedding functions, which was a little trickier thna I expected. In this blog post, we’ll explore how I failed and then succeeded at this task.

But first, let’s install ChromaDB:

pip install chromadb

The embedding functions live in the chromadb.utils.embedding_functions module. So my first thought was that I could list all the things defined in that module and then check which ones were a sub class of EmbeddingFunction:

import chromadb.utils.embedding_functions as ef

    cls_name in dir(ef)
    for cls_name in dir(ef)
    if issubclass(getattr(ef, cls_name), ef.EmbeddingFunction)

If we run this, we’ll see the following error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in <listcomp>
  File "/Users/markhneedham/Library/Caches/pypoetry/virtualenvs/chroma-example-SSMwZxEc-py3.11/lib/python3.11/site-packages/typing_extensions.py", line 662, in __subclasscheck__
    raise TypeError(
TypeError: Instance and class checks can only be used with @runtime_checkable protocols

From my understanding, we’d need EmbeddingFunction to have a @runtime_checkable annotation for this technique to work. ChatGPT guided me to the following alternative, where we check if EmbeddingFunction exists in in the base classes of a given class via the bases attribute:

import inspect

    for cls_name in dir(ef)
    if inspect.isclass(getattr(ef,cls_name)) and ef.EmbeddingFunction in getattr(ef,cls_name).__bases__

If we run that piece of code, we’ll see the following output:

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket