Skip to content

upstream(tinydb): query objects answer bool() and 'in' silently #137

Open

Description

@cdwilson

Tracks upstream friction in TinyDB. The explanation lives in the docs; this issue is the unit of work.

Explanation: Query objects answer bool() and in silently — 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

Upstream only — no tinydantic import.

from tinydb import Query, where

print("bool(where('name') == 'nobody'):", bool(where("name") == "nobody"))
print("'anything' in Query().name:     ", "anything" in Query().name)

Run with python repro.py.

Actual output:

bool(where('name') == 'nobody'): True
'anything' in Query().name:      True

Neither answer depends on the data — no table was even opened. QueryInstance defines no __bool__ and no __len__, so every condition is truthy; Query defines __getitem__ but no __iter__, so Python's legacy sequence protocol makes in iterate the query and report True for anything.

Expected: both raise TypeError, following the numpy/pandas ambiguous-truth precedent — if User.name == requested: is a mistake worth failing on, not a permanently-true expression that passes review.

Environment: TinyDB 4.9.0, Python 3.10.20, macOS. Run 2026-08-13.

What tinydantic carries today

GuardedQuery/GuardedCondition (src/tinydantic/_query.py), which raise QueryTypeError for bool(), membership, and integer indexing. Applied by reassigning __class__ on the condition TinyDB just built — no private names, but it depends on QueryInstance staying a plain __slots__-free class. Each of the ~15 public condition builders is overridden; a builder added by a future TinyDB would return an unguarded condition, degrading rather than breaking.

Upstream status

Not filed. No draft prepared.

What would close this

__bool__ on QueryInstance and __iter__ on Query raising TypeError (numpy/pandas precedent), plus rejecting non-string path steps in __getitem__ — or a public hook for the condition type a Query subclass builds — or a maintainer decision to carry the workaround indefinitely.

Assisted-by: Claude:claude-opus-5

Activity

  1. added
    enhancementNew feature or request
    upstreamTracks a defect or request in an upstream dependency
    ai-assistedCreated or investigated with help from an AI agent
    on Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ai-assistedCreated or investigated with help from an AI agentenhancementNew feature or requestupstreamTracks a defect or request in an upstream dependency

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions