Skip to content

Commit 8f9e721

Browse files
committed
py/objtype: Fix type hashing with metaclass operator support.
When MICROPY_PY_METACLASS_OPS is enabled, type_unary_op() intercepts all unary operations on type objects. Previously it returned MP_OBJ_NULL for types with the standard metaclass, which prevented the default hash implementation from being used. This fix ensures that __hash__ always works for type objects by returning the default identity-based hash when the metaclass doesn't override it. Fixes TypeError: unsupported type for __hash__: 'type' Signed-off-by: Andrew Leech <[email protected]>
1 parent 609b8aa commit 8f9e721

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
include("$(PORT_DIR)/variants/manifest.py")
22

33
include("$(MPY_DIR)/extmod/asyncio")
4+
5+
# Include enum module
6+
module("enum.py", base_path="$(MPY_DIR)/lib/enum")

py/objtype.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1274,8 +1274,13 @@ static mp_obj_t type_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
12741274
// by looking up special methods in the metaclass
12751275
mp_obj_type_t *self = MP_OBJ_TO_PTR(self_in);
12761276

1277-
// Fast path: standard type metaclass doesn't support operators
1277+
// Fast path: standard type metaclass doesn't support custom operators
1278+
// but we still need to handle __hash__ with default implementation
12781279
if (self->base.type == &mp_type_type) {
1280+
if (op == MP_UNARY_OP_HASH) {
1281+
// Use default hash based on object identity (address)
1282+
return MP_OBJ_NEW_SMALL_INT((mp_uint_t)self_in);
1283+
}
12791284
return MP_OBJ_NULL;
12801285
}
12811286

@@ -1313,6 +1318,12 @@ static mp_obj_t type_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
13131318
return val;
13141319
}
13151320

1321+
// Metaclass doesn't define the operator, use default for __hash__
1322+
if (op == MP_UNARY_OP_HASH) {
1323+
// Use default hash based on object identity (address)
1324+
return MP_OBJ_NEW_SMALL_INT((mp_uint_t)self_in);
1325+
}
1326+
13161327
return MP_OBJ_NULL; // op not supported
13171328
}
13181329

0 commit comments

Comments
 (0)