Repository navigation
Description
Tracks upstream friction in TinyDB. The explanation lives in the docs; this issue is the unit of work.
Explanation: Query.matches() is documented as whole-value and anchors only at the start — the limitation, why it matters to an ODM, the workaround tinydantic carries, and the change that would remove it. That section is written to be read standalone by an upstream maintainer, so it doubles as the ready-to-send proposal if we ever file this.
Reproduction
Query.matches() documents itself as "Run a regex test against a dict value (whole string has to match)" and implements the test with re.match, which anchors at the start only.
from tinydb import TinyDB
from tinydb.storages import MemoryStorage
from tinydantic import TinydanticModel
db = TinyDB(storage=MemoryStorage)
class User(TinydanticModel, database=db):
email: str
User(email="[email protected]").insert()
print(User.search(User.email.matches(r".*@example\.com")))Run with python repro.py.
Actual output:
[User(id=1, email='[email protected]')]
Expected from the documented "whole string has to match" contract: []. re.match succeeds on any prefix, so the trailing .evil is simply not looked at. re.fullmatch is the function the docstring describes.
Environment: TinyDB 4.9.0, tinydantic 0.4.0 at 719ca78, Python 3.10.20, pydantic 2.13.4, macOS. Run 2026-08-13.
What tinydantic carries today
No code workaround — the behavior is fine, the documentation is not, and changing the behavior upstream would break every existing prefix-matching caller. tinydantic's own GuardedQuery.matches() now documents the anchoring accurately and points at $, and docs/usage/queries.md does the same. Before this, tinydantic had copied the upstream wording verbatim and told users matches() tested the whole value.
The security shape is worth stating plainly: a reader who trusts the docstring writes email.matches(r".*@example\.com") as an allow-list and gets a filter that accepts [email protected].
Upstream status
Not filed. No draft prepared. Do not file without maintainer approval.
What would close this
A docstring correction upstream — "the pattern is matched against the start of the value (re.match); end it with $ to require a whole-value match" — plus, optionally, a fullmatch=/Query.fullmatch() spelling for the behavior the current wording promises. A behavior change to re.fullmatch is not being proposed: it would silently narrow every existing caller's results.
What was not done
The reproduction was run and its output pasted above. No fix was built or tested, nothing was filed upstream, and no upstream maintainer has been contacted.
Originally finding Q2 / D-QRY-3 of the 2026-08-13 docs and docstring audit.
Assisted-by: Claude:claude-opus-5
Activity
docs(query): correct matches() semantics and query docstrings