Should sqlite3.Row be more dict-like?

Last year, @vsajip suggested to add a __contains__ method to the sqlite3.Row class, with the following reasoning/pitch:

The sqlite3.Row class is supposed to give access to row results by name as well as index. So in some respects it behaves like a dictionary (it even has a keys() method) but it doesn’t appear to handle the in operator as one might expect.

I hesitate to add this, because it is not immediately obvious to me what item in row should check for; should it check for the existence of column names or row values. Currently in sqlite3, if you do not supply a row factory, a tuple will be returned, meaning item in row will check for row values. But it is not immediately obvious if that should direct how in should work for sqlite3.Row, especially since it feels dict like.

I recently revisited this issue on the tracker, and I came to the conclusion that I think the feature should be rejected, since it is not immediately obvious what __contains__ should return. OTOH, that’s a documentation issue, so my reason to reject it may be slightly thin.

Thoughts? (If I don’t get any response, I’ll close it as rejected in a week or two :slight_smile: )

1 Like

sqlite3.Row already handles the in operator (as a side effect of been iterable). Adding __contains__ with preserving the current behavior is a pure optimization, and is worth to be done only if it is a common operation (I doubt). Adding __contains__ with completely different semantic is a breaking change. Furthermore, it is a bug magnet, because of the difference between tuple and sqlite3.Row. It also breaks consistency with iteration.


Since the names of the columns are fixed by the sql select used it is not clear to me the utility of dict contains.


.__contains__() for a mapping/sequence object is always ambiguous, since default is to search values for sequences and keys for mappings.

Now, the in operator first looks for the .__contains__() method and then falls back to iterating over the object until it finds the value or the iterator is exhausted (see PySequence_Contains() et al.), so the current behavior of x in sqlite3.Row() is to search for values, not keys.

You may want to implement the sq_contains slot for Row objects as an optimization, but I doubt that this is worth the hassle, since I don’t think that people will use in on Row objects a lot - esp. not since it’s ambiguous.

I’d simply close the issue.


Thanks for you input; I’ve rejected the feature request.

1 Like