summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/obj.c24
-rw-r--r--py/qstrdefs.h1
2 files changed, 17 insertions, 8 deletions
diff --git a/py/obj.c b/py/obj.c
index e9fed19c6c..e581495888 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -172,17 +172,25 @@ mp_int_t mp_obj_hash(mp_obj_t o_in) {
return mp_obj_tuple_hash(o_in);
} else if (MP_OBJ_IS_TYPE(o_in, &mp_type_type)) {
return (mp_int_t)o_in;
+ } else if (MP_OBJ_IS_OBJ(o_in)) {
+ // if a valid __hash__ method exists, use it
+ mp_obj_t hash_method[2];
+ mp_load_method_maybe(o_in, MP_QSTR___hash__, hash_method);
+ if (hash_method[0] != MP_OBJ_NULL) {
+ mp_obj_t hash_val = mp_call_method_n_kw(0, 0, hash_method);
+ if (MP_OBJ_IS_INT(hash_val)) {
+ return mp_obj_int_get(hash_val);
+ }
+ }
+ }
- // TODO hash class and instances
- // TODO delegate to __hash__ method if it exists
+ // TODO hash class and instances - in CPython by default user created classes' __hash__ resolves to their id
+ if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "unhashable type"));
} else {
- if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "unhashable type"));
- } else {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
- "unhashable type: '%s'", mp_obj_get_type_str(o_in)));
- }
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
+ "unhashable type: '%s'", mp_obj_get_type_str(o_in)));
}
}
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index ecb1b96236..1506d0a261 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -39,6 +39,7 @@ Q(__locals__)
Q(__main__)
Q(__module__)
Q(__name__)
+Q(__hash__)
Q(__next__)
Q(__qualname__)
Q(__path__)