diff options
author | stijn <stinos@zoho.com> | 2014-11-12 14:57:34 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-11-15 18:24:22 +0000 |
commit | e00eeaf4cd4f937939d6713716255116cb06b7b9 (patch) | |
tree | b10ead4a9b2dbda4f7139f8c51cc9988cf45a20c /py | |
parent | d8474d3617c621abf78b06419808d455b6b1ae27 (diff) |
py: Use __hash__ method if a type defines it
Diffstat (limited to 'py')
-rw-r--r-- | py/obj.c | 24 | ||||
-rw-r--r-- | py/qstrdefs.h | 1 |
2 files changed, 17 insertions, 8 deletions
@@ -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 ecb1b9623..1506d0a26 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__) |