parent
4e0eeebdc2
commit
0182385ab0
14
py/objtype.c
14
py/objtype.c
|
@ -46,6 +46,8 @@
|
||||||
#define DEBUG_printf(...) (void)0
|
#define DEBUG_printf(...) (void)0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
// instance object
|
// instance object
|
||||||
|
|
||||||
|
@ -749,6 +751,8 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
|
||||||
assert(MP_OBJ_IS_TYPE(bases_tuple, &mp_type_tuple)); // Micro Python restriction, for now
|
assert(MP_OBJ_IS_TYPE(bases_tuple, &mp_type_tuple)); // Micro Python restriction, for now
|
||||||
assert(MP_OBJ_IS_TYPE(locals_dict, &mp_type_dict)); // Micro Python restriction, for now
|
assert(MP_OBJ_IS_TYPE(locals_dict, &mp_type_dict)); // Micro Python restriction, for now
|
||||||
|
|
||||||
|
// TODO might need to make a copy of locals_dict; at least that's how CPython does it
|
||||||
|
|
||||||
// Basic validation of base classes
|
// Basic validation of base classes
|
||||||
uint len;
|
uint len;
|
||||||
mp_obj_t *items;
|
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)
|
||||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "multiple bases have instance lay-out conflict"));
|
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "multiple bases have instance lay-out conflict"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mp_map_t *locals_map = mp_obj_dict_get_map(o->locals_dict);
|
||||||
|
mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP);
|
||||||
|
if (elem != NULL) {
|
||||||
|
// __new__ slot exists; check if it is a function
|
||||||
|
if (MP_OBJ_IS_TYPE(elem->value, &mp_type_fun_native) || MP_OBJ_IS_TYPE(elem->value, &mp_type_fun_bc)) {
|
||||||
|
// __new__ is a function, wrap it in a staticmethod decorator
|
||||||
|
elem->value = static_class_method_make_new((mp_obj_t)&mp_type_staticmethod, 1, 0, &elem->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
class A:
|
class A:
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def __new__(cls):
|
def __new__(cls):
|
||||||
print("A.__new__")
|
print("A.__new__")
|
||||||
return super(cls, A).__new__(cls)
|
return super(cls, A).__new__(cls)
|
||||||
|
@ -9,13 +7,21 @@ class A:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def meth(self):
|
def meth(self):
|
||||||
pass
|
print('A.meth')
|
||||||
|
|
||||||
#print(A.__new__)
|
#print(A.__new__)
|
||||||
#print(A.__init__)
|
#print(A.__init__)
|
||||||
|
|
||||||
a = A()
|
a = A()
|
||||||
|
a.meth()
|
||||||
|
|
||||||
|
a = A.__new__(A)
|
||||||
|
a.meth()
|
||||||
|
|
||||||
#print(a.meth)
|
#print(a.meth)
|
||||||
#print(a.__init__)
|
#print(a.__init__)
|
||||||
#print(a.__new__)
|
#print(a.__new__)
|
||||||
|
|
||||||
|
# __new__ should automatically be a staticmethod, so this should work
|
||||||
|
a = a.__new__(A)
|
||||||
|
a.meth()
|
||||||
|
|
Loading…
Reference in New Issue