piccolo
piccolo copied to clipboard
Increase type strictness for `where` clause to prevent accidental joins using `and` instead of `&`
Ran into an issue where I was doing an incorrect and clause, as follows:
def following(self, user: "User") -> bool:
"""
Return whether the user is following the queue
"""
t = TQueueFollow\
.exists()\
.where(
TQueueFollow.queue == self.id
and TQueueFollow.user == user.id
).run_sync()
assert isinstance(t, bool)
return t
The mistake I made is that I used and instead of & to build the clause. If possible, some additional type constraints should be added so that tools such as mypy will detect this error.
Yeah, interesting.
We have a check here:
https://github.com/piccolo-orm/piccolo/blob/248c209cb3de26181aac907a68552f525dc182f2/piccolo/query/mixins.py#L171-L179
But the intention was to catch errors like MyTable.select().where(MyTable.some_column is 1).
In that example, MyTable.some_column is 1 returns a boolean, so we catch that.
But in your example, it uses and. So:
TQueueFollow.queue == self.id and TQueueFollow.user == user.id
Is evaluated to:
TQueueFollow.user == user.id
Which is a valid statement for where.
So it's actually really tricky! We can't override and in Python either (to my knowledge).