Query.any/all treat strings as sequences, causing false matches
Author: uadhranCreated Sep 15, 2026Updated Sep 16, 2026
Description
Query.any / Query.all (value-list form) use:
def is_sequence(obj):
return hasattr(obj, '__iter__')(tinydb/queries.py)
Strings (and bytes, dicts, etc.) are iterable, so a string field is treated like a list of characters. That yields false positives that the docs do not describe (docs talk about list fields).
Verified on current master (4aa5311, TinyDB 4.9.0).
Minimal reproduction
from tinydb.queries import Query
Q = Query()
print(Q.name.any(['a', 'b'])({'name': 'abc'})) # True (unexpected)
print(Q.name.all(['a', 'b'])({'name': 'abc'})) # True (unexpected)Why: iterating 'abc' yields 'a', 'b', 'c', and 'a' in ['a','b'] / 'b' in ['a','b'].
Same class of surprise for bytes and for dict fields (iterates keys).
Expected behavior (for discussion)
Possible directions:
- Treat only real sequences that are not
str/bytes(e.g.list/tuple, orcollections.abc.Sequenceexcluding text/bytes) - Keep current behavior but document that string fields are treated as character sequences
- Something else you prefer
For typical document fields, (1) matches user expectations and the current docs.
Suggested tests
Query().name.any(['a','b'])on{'name': 'abc'}→False(if option 1)- Existing list-field
any/alltests keep passing - Optional:
bytes/ mapping field cases
Happy to open a PR once the preferred behavior is clear.
Environment
- TinyDB 4.9.0 /
master@4aa5311
Source: msiemens/tinydb