Example #1
0
 def hash(space, w_obj):
     w_hash = space.lookup(w_obj, '__hash__')
     if w_hash is None:
         # xxx there used to be logic about "do we have __eq__ or __cmp__"
         # here, but it does not really make sense, as 'object' has a
         # default __hash__.  This path should only be taken under very
         # obscure circumstances.
         return default_identity_hash(space, w_obj)
     if space.is_w(w_hash, space.w_None):
         typename = space.type(w_obj).getname(space)
         raise operationerrfmt(space.w_TypeError,
                               "'%s' objects are unhashable", typename)
     w_result = space.get_and_call_function(w_hash, w_obj)
     w_resulttype = space.type(w_result)
     if space.is_w(w_resulttype, space.w_int):
         return w_result
     elif space.is_w(w_resulttype, space.w_long):
         return space.hash(w_result)
     elif space.is_true(space.isinstance(w_result, space.w_int)):
         # be careful about subclasses of 'int'...
         return space.wrap(space.int_w(w_result))
     elif space.is_true(space.isinstance(w_result, space.w_long)):
         # be careful about subclasses of 'long'...
         bigint = space.bigint_w(w_result)
         return space.wrap(bigint.hash())
     else:
         raise OperationError(
             space.w_TypeError,
             space.wrap("__hash__() should return an int or long"))
Example #2
0
    def hash(space, w_obj):
        w_hash = space.lookup(w_obj, '__hash__')
        if w_hash is None:
            # xxx there used to be logic about "do we have __eq__ or __cmp__"
            # here, but it does not really make sense, as 'object' has a
            # default __hash__.  This path should only be taken under very
            # obscure circumstances.
            return default_identity_hash(space, w_obj)
        if space.is_w(w_hash, space.w_None):
            raise oefmt(space.w_TypeError, "'%T' objects are unhashable",
                        w_obj)
        w_result = space.get_and_call_function(w_hash, w_obj)

        # issue 2346 : returns now -2 for hashing -1 like cpython
        if space.isinstance_w(w_result, space.w_int):
            h = space.int_w(w_result)
        elif space.isinstance_w(w_result, space.w_long):
            bigint = space.bigint_w(w_result)
            h = bigint.hash()
        else:
            raise oefmt(space.w_TypeError,
                        "__hash__() should return an int or long")
        # turn -1 into -2 without using a condition, which would
        # create a potential bridge in the JIT
        h -= (h == -1)
        return space.newint(h)
Example #3
0
    def hash(space, w_obj):
        w_hash = space.lookup(w_obj, '__hash__')
        if w_hash is None:
            # xxx there used to be logic about "do we have __eq__ or __cmp__"
            # here, but it does not really make sense, as 'object' has a
            # default __hash__.  This path should only be taken under very
            # obscure circumstances.
            return default_identity_hash(space, w_obj)
        if space.is_w(w_hash, space.w_None):
            raise oefmt(space.w_TypeError, "'%T' objects are unhashable",
                        w_obj)
        w_result = space.get_and_call_function(w_hash, w_obj)
        if not space.isinstance_w(w_result, space.w_int):
            raise oefmt(space.w_TypeError,
                        "__hash__ method should return an integer")

        from pypy.objspace.std.intobject import (W_AbstractIntObject,
                                                 W_IntObject)
        if not isinstance(w_result, W_IntObject):
            # a non W_IntObject int, assume long-like
            assert isinstance(w_result, W_AbstractIntObject)
            w_result = w_result.descr_hash(space)
        result = space.int_w(w_result)
        # turn -1 into -2 without using a condition, which would
        # create a potential bridge in the JIT
        result -= (result == -1)
        return space.newint(result)
Example #4
0
 def hash(space, w_obj):
     w_hash = space.lookup(w_obj, "__hash__")
     if w_hash is None:
         # xxx there used to be logic about "do we have __eq__ or __cmp__"
         # here, but it does not really make sense, as 'object' has a
         # default __hash__.  This path should only be taken under very
         # obscure circumstances.
         return default_identity_hash(space, w_obj)
     # XXX CPython has a special case for types with "__hash__ = None"
     # to produce a nicer error message, namely "unhashable type: 'X'".
     w_result = space.get_and_call_function(w_hash, w_obj)
     w_resulttype = space.type(w_result)
     if space.is_w(w_resulttype, space.w_int):
         return w_result
     elif space.is_w(w_resulttype, space.w_long):
         return space.hash(w_result)
     elif space.is_true(space.isinstance(w_result, space.w_int)):
         # be careful about subclasses of 'int'...
         return space.wrap(space.int_w(w_result))
     elif space.is_true(space.isinstance(w_result, space.w_long)):
         # be careful about subclasses of 'long'...
         bigint = space.bigint_w(w_result)
         return space.wrap(bigint.hash())
     else:
         raise OperationError(space.w_TypeError, space.wrap("__hash__() should return an int or long"))
Example #5
0
 def hash(space, w_obj):
     w_hash = space.lookup(w_obj, '__hash__')
     if w_hash is None:
         # xxx there used to be logic about "do we have __eq__ or __cmp__"
         # here, but it does not really make sense, as 'object' has a
         # default __hash__.  This path should only be taken under very
         # obscure circumstances.
         return default_identity_hash(space, w_obj)
     if space.is_w(w_hash, space.w_None):
         raise operationerrfmt(space.w_TypeError,
                               "'%T' objects are unhashable", w_obj)
     w_result = space.get_and_call_function(w_hash, w_obj)
     w_resulttype = space.type(w_result)
     if space.is_w(w_resulttype, space.w_int):
         return w_result
     elif space.is_w(w_resulttype, space.w_long):
         return space.hash(w_result)
     elif space.isinstance_w(w_result, space.w_int):
         # be careful about subclasses of 'int'...
         return space.wrap(space.int_w(w_result))
     elif space.isinstance_w(w_result, space.w_long):
         # be careful about subclasses of 'long'...
         bigint = space.bigint_w(w_result)
         return space.wrap(bigint.hash())
     else:
         raise OperationError(space.w_TypeError,
                 space.wrap("__hash__() should return an int or long"))
Example #6
0
    def hash(space, w_obj):
        w_hash = space.lookup(w_obj, '__hash__')
        if w_hash is None:
            # xxx there used to be logic about "do we have __eq__ or __cmp__"
            # here, but it does not really make sense, as 'object' has a
            # default __hash__.  This path should only be taken under very
            # obscure circumstances.
            return default_identity_hash(space, w_obj)
        if space.is_w(w_hash, space.w_None):
            raise oefmt(space.w_TypeError,
                        "'%T' objects are unhashable", w_obj)
        w_result = space.get_and_call_function(w_hash, w_obj)
        if not space.isinstance_w(w_result, space.w_int):
            raise oefmt(space.w_TypeError,
                        "__hash__ method should return an integer")

        from pypy.objspace.std.intobject import (
            W_AbstractIntObject, W_IntObject)
        if type(w_result) is W_IntObject:
            return w_result
        elif isinstance(w_result, W_IntObject):
            return space.wrap(space.int_w(w_result))
        # a non W_IntObject int, assume long-like
        assert isinstance(w_result, W_AbstractIntObject)
        return w_result.descr_hash(space)
Example #7
0
 def hash(space, w_obj):
     w_hash = space.lookup(w_obj, '__hash__')
     if w_hash is None:
         # xxx there used to be logic about "do we have __eq__ or __cmp__"
         # here, but it does not really make sense, as 'object' has a
         # default __hash__.  This path should only be taken under very
         # obscure circumstances.
         return default_identity_hash(space, w_obj)
     # XXX CPython has a special case for types with "__hash__ = None"
     # to produce a nicer error message, namely "unhashable type: 'X'".
     w_result = space.get_and_call_function(w_hash, w_obj)
     w_resulttype = space.type(w_result)
     if space.is_w(w_resulttype, space.w_int):
         return w_result
     elif space.is_w(w_resulttype, space.w_long):
         return space.hash(w_result)
     elif space.is_true(space.isinstance(w_result, space.w_int)):
         # be careful about subclasses of 'int'...
         return space.wrap(space.int_w(w_result))
     elif space.is_true(space.isinstance(w_result, space.w_long)):
         # be careful about subclasses of 'long'...
         bigint = space.bigint_w(w_result)
         return space.wrap(bigint.hash())
     else:
         raise OperationError(
             space.w_TypeError,
             space.wrap("__hash__() should return an int or long"))
Example #8
0
    def hash(space, w_obj):
        w_hash = space.lookup(w_obj, '__hash__')
        if w_hash is None:
            # xxx there used to be logic about "do we have __eq__ or __cmp__"
            # here, but it does not really make sense, as 'object' has a
            # default __hash__.  This path should only be taken under very
            # obscure circumstances.
            return default_identity_hash(space, w_obj)
        if space.is_w(w_hash, space.w_None):
            raise oefmt(space.w_TypeError,
                        "'%T' objects are unhashable", w_obj)
        w_result = space.get_and_call_function(w_hash, w_obj)

        # issue 2346 : returns now -2 for hashing -1 like cpython
        if space.isinstance_w(w_result, space.w_int):
            h = space.int_w(w_result)
        elif space.isinstance_w(w_result, space.w_long):
            bigint = space.bigint_w(w_result)
            h = bigint.hash()
        else:
            raise oefmt(space.w_TypeError,
                        "__hash__() should return an int or long")
        # turn -1 into -2 without using a condition, which would
        # create a potential bridge in the JIT
        h -= (h == -1)
        return space.wrap(h)
Example #9
0
 def hash(space, w_obj):
     w_hash = space.lookup(w_obj, '__hash__')
     if w_hash is None:
         if space.lookup(w_obj, '__eq__') is not None or \
            space.lookup(w_obj, '__cmp__') is not None:
             raise OperationError(space.w_TypeError,
                                  space.wrap("unhashable type"))
         return default_identity_hash(space, w_obj)
     w_result = space.get_and_call_function(w_hash, w_obj)
     if space.is_true(space.isinstance(w_result, space.w_int)):
         return w_result
     else:
         raise OperationError(space.w_TypeError,
                              space.wrap("__hash__() should return an int"))
Example #10
0
 def hash(space, w_obj):
     w_hash = space.lookup(w_obj, '__hash__')
     if w_hash is None:
         if space.lookup(w_obj, '__eq__') is not None or \
            space.lookup(w_obj, '__cmp__') is not None: 
             raise OperationError(space.w_TypeError, 
                                  space.wrap("unhashable type"))
         return default_identity_hash(space, w_obj)
     w_result = space.get_and_call_function(w_hash, w_obj)
     if space.is_true(space.isinstance(w_result, space.w_int)): 
         return w_result 
     else: 
         raise OperationError(space.w_TypeError, 
                  space.wrap("__hash__() should return an int"))