• Matthew Johnson's avatar
    Add __hash__() and __eq__() to MemoryViewSliceType to avoid distinct · 5e77573c
    Matthew Johnson authored
    object id hashes resulting in duplicate utility code in specialization
    
    The CppClassType.specialize() method uses a hash table to avoid
    re-generating specializations and thus, for example, re-generating utility code:
    
        # values is a dict where values are instances of classes in
        # PyrexTypes.py
        key = tuple(values.items())
        if key in self.specializations:
            return self.specializations[key]
        # instantiate new CppClassType, eventually resulting in utility code
    
    However, because MemoryViewSliceType used the default (object-id) hash,
    distinct MemoryViewSliceType instances would ultimately give rise to
    distinct keys. As a result, code like
    
         def test_memviews_same(a,b):
             cdef vector[double[:]] aa = a
             cdef vector[double[:]] bb = b
    
    would successfully pass through the Cython compiler but then result in a
    C++ compiler error due to redefinition of utility code:
    
        error: redefinition of 'std::vector<__Pyx_memviewslice> __pyx_convert_vector_from_py___Pyx_memviewslice(PyObject*)'
    
    To allow the hash table in CppClassType.specialize() to identify 'equal'
    specializations of CppClassType, we can add __hash__() and __eq__()
    methods based on the existing
    MemoryViewSliceType.same_as_resolved_type() method. Other classes in
    PyrexTypes.py also have __hash__() methods defined and the choices made
    here appear roughly consistent.
    
    This addition allows the above example to compile successfully.
    5e77573c
PyrexTypes.py 150 KB