<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body bgcolor="#ffffff" text="#000000">
<br>
<br>
Attached is a patch for review.<br>
<br>
As of revision 57341 (only a couple hours old as of this writing),
test_shelve was failing on my machine.&nbsp; This was because I didn't have
any swell databases available, so anydbm was falling back to dumbdbm,
and dumbdbm had a bug.&nbsp; In Py3k, dumbdbm's dict-like interface now
requires byte objects, which it internally encodes to "latin-1" then
uses with a real dict.&nbsp; But dumbdbm.__contains__ was missing the
conversion, so it was trying to use a bytes object with a real dict,
and that failed with an error (as bytes objects are not hashable).&nbsp;
This patch fixes dumbdbm.__contains__ so it encodes the key, fixing
test_shelve on my machine.<br>
<br>
But there's more!&nbsp; Neil Norvitz pointed out that test_shelve <i>didn't</i>
fail on his machine.&nbsp; That's because dumbdbm is the last resort of
anydbm, and he had a superior database module available.&nbsp; So the
regression test suite was really missing two things:<br>
<ul>
  <li>test_dumbdbm should test dumbdbm.__contains__.</li>
  <li>test_anydbm should test all the database modules available, not
merely its first choice.<br>
  </li>
</ul>
So this patch also adds test_write_contains() to test_dumbdbm, and a
new external function to test_anydbm: dbm_iterate(), which returns an
iterator over all database modules available to anydbm, <i>and</i>
internally forces anydbm to use that database module, restoring anydbm
to its first choice when it finishes iteration.&nbsp; I also renamed
_delete_files() to delete_files() so it could be the canonical dbm
cleanup function for other tests.<br>
<br>
While I was at it, I noticed that test_whichdbm.py did a good job of
testing all the databases available, but with a slightly odd approach:
it iterated over all the possible databases, and created new test
methods--inserting them into the class object--for each one that was
available.&nbsp; I changed it to use dbm_iterate() and delete_files() from
test.test_anydbm, so that that logic can live in only one place.&nbsp; I
didn't preserve the setattr() approach; I simply iterate over all the
modules and run the tests inside one conventional method.<br>
<br>
One final thought, for the folks who defined this "in Py3k,
database-backed dict-like objects use byte objects as keys" interface.&nbsp;
dumbdbm.keys() returns self._index.keys(), which means that it's
serving up real strings, not byte objects.&nbsp; Shouldn't it return
[k.encode("latin-1") for k in self._index.keys()] ?&nbsp; (Or perhaps change
iterkeys to return that as a generator expression, and change keys() to
return list(self.iterkeys())?)<br>
<br>
Thanks,<br>
<br>
<br>
<i>larry</i>
</body>
</html>