diff options
| author | Daniël van de Giessen <daniel@dvdgiessen.nl> | 2020-12-07 13:33:13 +0100 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2023-10-13 15:11:49 +1100 |
| commit | 4f5e165d0bf9ba338df3cdab4266556c4c5a70c7 (patch) | |
| tree | 089d5d3281ac7bda910c4d8a0fdeb87f774501bf /py | |
| parent | 5f0bd33b732151bb7aa896307afae55400b15454 (diff) | |
py/objboundmeth: Support comparing and hashing bound methods.
This behaviour matches CPython. It's useful to be able to store bound
method objects in dicts/sets, and compare for equality, eg when storing
them in a list and using list.remove().
Signed-off-by: Daniël van de Giessen <daniel@dvdgiessen.nl>
Diffstat (limited to 'py')
| -rw-r--r-- | py/obj.h | 1 | ||||
| -rw-r--r-- | py/objboundmeth.c | 25 |
2 files changed, 24 insertions, 2 deletions
@@ -828,6 +828,7 @@ extern const mp_obj_type_t mp_type_fun_bc; extern const mp_obj_type_t mp_type_module; extern const mp_obj_type_t mp_type_staticmethod; extern const mp_obj_type_t mp_type_classmethod; +extern const mp_obj_type_t mp_type_bound_meth; extern const mp_obj_type_t mp_type_property; extern const mp_obj_type_t mp_type_stringio; extern const mp_obj_type_t mp_type_bytesio; diff --git a/py/objboundmeth.c b/py/objboundmeth.c index 8486f876f..10f52016c 100644 --- a/py/objboundmeth.c +++ b/py/objboundmeth.c @@ -83,6 +83,25 @@ STATIC mp_obj_t bound_meth_call(mp_obj_t self_in, size_t n_args, size_t n_kw, co return mp_call_method_self_n_kw(self->meth, self->self, n_args, n_kw, args); } +STATIC mp_obj_t bound_meth_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + mp_obj_bound_meth_t *self = MP_OBJ_TO_PTR(self_in); + switch (op) { + case MP_UNARY_OP_HASH: + return MP_OBJ_NEW_SMALL_INT((mp_uint_t)self->self ^ (mp_uint_t)self->meth); + default: + return MP_OBJ_NULL; // op not supported + } +} + +STATIC mp_obj_t bound_meth_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + if (!mp_obj_is_type(rhs_in, &mp_type_bound_meth) || op != MP_BINARY_OP_EQUAL) { + return MP_OBJ_NULL; // op not supported + } + mp_obj_bound_meth_t *lhs = MP_OBJ_TO_PTR(lhs_in); + mp_obj_bound_meth_t *rhs = MP_OBJ_TO_PTR(rhs_in); + return mp_obj_new_bool(lhs->self == rhs->self && lhs->meth == rhs->meth); +} + #if MICROPY_PY_FUNCTION_ATTRS STATIC void bound_meth_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (dest[0] != MP_OBJ_NULL) { @@ -107,13 +126,15 @@ STATIC void bound_meth_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { #define BOUND_METH_TYPE_ATTR #endif -STATIC MP_DEFINE_CONST_OBJ_TYPE( +MP_DEFINE_CONST_OBJ_TYPE( mp_type_bound_meth, MP_QSTR_bound_method, MP_TYPE_FLAG_NONE, BOUND_METH_TYPE_PRINT BOUND_METH_TYPE_ATTR - call, bound_meth_call + call, bound_meth_call, + unary_op, bound_meth_unary_op, + binary_op, bound_meth_binary_op ); mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self) { |
