@@ -313,9 +313,6 @@ def generic_repr(self):
313313 cls .__str__ = generic_str
314314 cls .__repr__ = generic_repr
315315
316- if not hasattr (cls , "__hash__" ):
317- raise AssertionError (f"not hashable: { cls } " )
318-
319316 # }}}
320317
321318 # {{{ Python set-like behavior
@@ -908,6 +905,12 @@ def val_to_python(self):
908905 # note: automatic upcasts for method arguments are provided through
909906 # 'implicitly_convertible' on the C++ side of the wrapper.
910907
908+ def make_upcasting_hash (special_method , upcast_method ):
909+ def wrapper (basic_instance ):
910+ return hash ((type (basic_instance ), upcast_method (basic_instance )))
911+
912+ return wrapper
913+
911914 def make_new_upcast_wrapper (method , upcast ):
912915 # This function provides a scope in which method and upcast
913916 # are not changed from one iteration of the enclosing for
@@ -916,7 +919,6 @@ def make_new_upcast_wrapper(method, upcast):
916919 def wrapper (basic_instance , * args , ** kwargs ):
917920 special_instance = upcast (basic_instance )
918921 return method (special_instance , * args , ** kwargs )
919-
920922 return wrapper
921923
922924 def make_existing_upcast_wrapper (basic_method , special_method , upcast ):
@@ -938,6 +940,18 @@ def wrapper(basic_instance, *args, **kwargs):
938940 def add_upcasts (basic_class , special_class , upcast_method ):
939941 from functools import update_wrapper
940942
943+ # {{{ implicitly upcast __hash__
944+
945+ # We don't use hasattr() here because in the C++ part of the wrapper
946+ # we overwrite pybind's unwanted default __hash__ implementation
947+ # with None.
948+ if (getattr (basic_class , "__hash__" , None ) is None
949+ and getattr (special_class , "__hash__" , None ) is not None ):
950+ wrapper = make_upcasting_hash (special_class .__hash__ , upcast_method )
951+ basic_class .__hash__ = update_wrapper (wrapper , basic_class .__hash__ )
952+
953+ # }}}
954+
941955 def my_ismethod (class_ , method_name ):
942956 if method_name .startswith ("_" ):
943957 return False
0 commit comments