On Feb 17, 3:25 pm, Simon King <simon.k...@uni-jena.de> wrote: > However, subclasses forget everything about the hash: > sage: class Bar(Foo): > ....: pass > ....: > sage: b = Bar() > sage: hash(b) == id(b) > False > sage: hash(b) == id(b) >> 4 > True
OK, I think I've found the problem. I think cython people can comment on this. Consider the following example: -------------------[cython code]----------------------------- cdef extern from "object.h": ctypedef struct RichPyTypeObject "PyTypeObject": void * tp_hash cdef long myhash(void * v): return <long>v cdef class MyHash(object): def __hash__(self): return 0 pass (<RichPyTypeObject *>MyHash).tp_hash = &myhash --------------------------------------------------------- For the most part this seems to work: sage: a=MyHash() sage: hash(a) == id(a) True However, indeed as you describe: sage: class B(MyHash): pass sage: b=B() sage: hash(b) 0 The only reason I can think of for inheritance not to pick up on the changed tp_hash field is that PyType_Ready gets called on the data structure formed for MyHash before we get a chance to change the tp_hash field. Apparently PyType_Ready saves or copies some things that get used for inheritance later. Inserting the right pointer (i.e., &myhash rather than &MyHash.__hash__) would be trivial if we were to get to process/edit the resulting ".c" file, but it seems impossible in cython at the moment. Indeed, we have sage: MyHash.__dict__["__hash__"](h) 0 sage: print MyHash.__hash__(h) 0 sage: h.__hash__() 0 In other words, scribbling over tp_hash after PyType_Ready has been called makes for an imperfect hash override. You'd also need to change the __hash__ entry on in the MyHash dictproxy (which you can't!) This also affects the __classcall__ hack you proposed. You'll see there as well that hash(a) and a.__hash__() diverge, which we can't afford to happen. The quickest solution is to write UniqueRepresentation as an extension class *in C*. Then you can insert your superquick hash function into tp_hash before calling PyType_Ready. -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-devel@googlegroups.com. Visit this group at http://groups.google.com/group/sage-devel?hl=en. For more options, visit https://groups.google.com/groups/opt_out.