Re: [pypy-dev] [pypy-svn] r29534 - pypy/dist/pypy/rpython/ootypesystem/test
antocuni@codespeak.net wrote:
Author: antocuni Date: Fri Jun 30 16:08:16 2006 New Revision: 29534
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oorecord.py Log: Added a failing test.
Basically, if we modify the Record after its hash has already been computed, we might obtain two objects that compare equal but hash differently.
Disabling the caching in LowLevelType.__hash__ fix the test, but I think it's not what we want.
Adding the following __hash__ to ootype.Record also fix the test, but I'm not sure if it's correct, especially with recursive structures:
def __hash__(self): return hash(self._fields)
Records are really like lltypesystem Structs, although because some of their code was copied from Instance, they may give the impression that you can add fields after the fact, but that should not be done, it breaks the fact that they are supposed to compare by structure. If you are needing that you need some other approach or introduce some kind of forward definition. _add_fields should really disappear from Record.
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oorecord.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_oorecord.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_oorecord.py Fri Jun 30 16:08:16 2006 @@ -38,3 +38,14 @@ t.a = 1 t.b = 2 assert ooidentityhash(t) != ooidentityhash(t2) + +import py +def test_hash(): + #py.test.skip("LowLevelType.__hash__ bug waiting to be fixed") + T1 = Record({"item0": Signed, "item1": Signed}) + T2 = Record({"item0": Signed}) + + hash(T2) # compute the hash, it will stored in __cached_hash + T2._add_fields({"item1": Signed}) # modify the object + assert T1 == T2 + assert hash(T1) == hash(T2) _______________________________________________ pypy-svn mailing list pypy-svn@codespeak.net http://codespeak.net/mailman/listinfo/pypy-svn
Samuele Pedroni wrote:
Records are really like lltypesystem Structs, although because some of their code was copied from Instance, they may give the impression that you can add fields after the fact, but that should not be done, it breaks the fact that they are supposed to compare by structure.
If you are needing that you need some other approach or introduce some kind of forward definition.
_add_fields should really disappear from Record.
ok, so it's my fault, but it don't solve my original problem. The problem is that TestCliTuple.test_inst_tuple_add_getitem in test_rpython.py used to fail because the IL code contained two copies of the same Record. After a bit of investigation I discovered that the reason was because I got two Records that compare equal but have different hashes; again, the problem was that the __cached_hash was different from the real one. Then I tried to reproduce the bug, and so I wrote the failing test, thinking that using _add_fields was fine. But after your comment I've understood that this is not the point, because Record._add_fields is called only in its __init__. For now the problem is worked-around in database.py (the lines marked with "XXX: temporary hack"), but the bug is still here: any idea of why I get two equal Records with different hashes? ciao Anto
Ok, I've found the bug, it's entirely a my fault, because in translator/cli/record.py I attach a new attribute _name to the Record, so the hash is no longer valid. Probably it's safer to store the name in some dictionary. ciao Anto
Hi Antonio, On Fri, Jun 30, 2006 at 08:54:18PM +0200, Antonio Cuni wrote:
Probably it's safer to store the name in some dictionary.
It's even required, yes: no mutating of the low-level type objects please :-) The case of Instance is a bit special in this respect. A bientot, Armin
participants (3)
-
Antonio Cuni
-
Armin Rigo
-
Samuele Pedroni