|
46 | 46 | #define DEBUG_printf(...) (void)0 |
47 | 47 | #endif |
48 | 48 |
|
| 49 | +STATIC mp_obj_t static_class_method_make_new(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args); |
| 50 | + |
49 | 51 | /******************************************************************************/ |
50 | 52 | // instance object |
51 | 53 |
|
@@ -749,6 +751,8 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) |
749 | 751 | assert(MP_OBJ_IS_TYPE(bases_tuple, &mp_type_tuple)); // Micro Python restriction, for now |
750 | 752 | assert(MP_OBJ_IS_TYPE(locals_dict, &mp_type_dict)); // Micro Python restriction, for now |
751 | 753 |
|
| 754 | + // TODO might need to make a copy of locals_dict; at least that's how CPython does it |
| 755 | + |
752 | 756 | // Basic validation of base classes |
753 | 757 | uint len; |
754 | 758 | mp_obj_t *items; |
@@ -783,6 +787,16 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) |
783 | 787 | nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "multiple bases have instance lay-out conflict")); |
784 | 788 | } |
785 | 789 |
|
| 790 | + mp_map_t *locals_map = mp_obj_dict_get_map(o->locals_dict); |
| 791 | + mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP); |
| 792 | + if (elem != NULL) { |
| 793 | + // __new__ slot exists; check if it is a function |
| 794 | + if (MP_OBJ_IS_TYPE(elem->value, &mp_type_fun_native) || MP_OBJ_IS_TYPE(elem->value, &mp_type_fun_bc)) { |
| 795 | + // __new__ is a function, wrap it in a staticmethod decorator |
| 796 | + elem->value = static_class_method_make_new((mp_obj_t)&mp_type_staticmethod, 1, 0, &elem->value); |
| 797 | + } |
| 798 | + } |
| 799 | + |
786 | 800 | return o; |
787 | 801 | } |
788 | 802 |
|
|
0 commit comments