@@ -172,17 +172,25 @@ mp_int_t mp_obj_hash(mp_obj_t o_in) {
172172 return mp_obj_tuple_hash (o_in );
173173 } else if (MP_OBJ_IS_TYPE (o_in , & mp_type_type )) {
174174 return (mp_int_t )o_in ;
175+ } else if (MP_OBJ_IS_OBJ (o_in )) {
176+ // if a valid __hash__ method exists, use it
177+ mp_obj_t hash_method [2 ];
178+ mp_load_method_maybe (o_in , MP_QSTR___hash__ , hash_method );
179+ if (hash_method [0 ] != MP_OBJ_NULL ) {
180+ mp_obj_t hash_val = mp_call_method_n_kw (0 , 0 , hash_method );
181+ if (MP_OBJ_IS_INT (hash_val )) {
182+ return mp_obj_int_get (hash_val );
183+ }
184+ }
185+ }
175186
176- // TODO hash class and instances
177- // TODO delegate to __hash__ method if it exists
187+ // TODO hash class and instances - in CPython by default user created classes' __hash__ resolves to their id
178188
189+ if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE ) {
190+ nlr_raise (mp_obj_new_exception_msg (& mp_type_TypeError , "unhashable type" ));
179191 } else {
180- if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE ) {
181- nlr_raise (mp_obj_new_exception_msg (& mp_type_TypeError , "unhashable type" ));
182- } else {
183- nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_TypeError ,
184- "unhashable type: '%s'" , mp_obj_get_type_str (o_in )));
185- }
192+ nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_TypeError ,
193+ "unhashable type: '%s'" , mp_obj_get_type_str (o_in )));
186194 }
187195}
188196
0 commit comments