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"))
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)
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)
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"))
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"))
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)
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"))
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)
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"))