@@ -90,17 +90,22 @@ STATIC mp_obj_t native_base_init_wrapper(size_t n_args, const mp_obj_t *args) {
9090}
9191STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (native_base_init_wrapper_obj , 1 , MP_OBJ_FUN_ARGS_MAX , native_base_init_wrapper );
9292
93- STATIC mp_obj_t mp_obj_new_instance (const mp_obj_type_t * class , size_t subobjs ) {
94- mp_obj_instance_t * o = m_new_obj_var (mp_obj_instance_t , mp_obj_t , subobjs );
93+ #if !MICROPY_CPYTHON_COMPAT
94+ STATIC
95+ #endif
96+ mp_obj_instance_t * mp_obj_new_instance (const mp_obj_type_t * class , const mp_obj_type_t * * native_base ) {
97+ size_t num_native_bases = instance_count_native_bases (class , native_base );
98+ assert (num_native_bases < 2 );
99+ mp_obj_instance_t * o = m_new_obj_var (mp_obj_instance_t , mp_obj_t , num_native_bases );
95100 o -> base .type = class ;
96101 mp_map_init (& o -> members , 0 );
97102 // Initialise the native base-class slot (should be 1 at most) with a valid
98103 // object. It doesn't matter which object, so long as it can be uniquely
99104 // distinguished from a native class that is initialised.
100- if (subobjs != 0 ) {
105+ if (num_native_bases != 0 ) {
101106 o -> subobj [0 ] = MP_OBJ_FROM_PTR (& native_base_init_wrapper_obj );
102107 }
103- return MP_OBJ_FROM_PTR ( o ) ;
108+ return o ;
104109}
105110
106111// TODO
@@ -267,20 +272,6 @@ STATIC void instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
267272mp_obj_t mp_obj_instance_make_new (const mp_obj_type_t * self , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
268273 assert (mp_obj_is_instance_type (self ));
269274
270- const mp_obj_type_t * native_base = NULL ;
271- size_t num_native_bases = instance_count_native_bases (self , & native_base );
272- assert (num_native_bases < 2 );
273-
274- mp_obj_instance_t * o = MP_OBJ_TO_PTR (mp_obj_new_instance (self , num_native_bases ));
275-
276- // This executes only "__new__" part of instance creation.
277- // TODO: This won't work well for classes with native bases.
278- // TODO: This is a hack, should be resolved along the lines of
279- // https://github.com/micropython/micropython/issues/606#issuecomment-43685883
280- if (n_args == 1 && * args == MP_OBJ_SENTINEL ) {
281- return MP_OBJ_FROM_PTR (o );
282- }
283-
284275 // look for __new__ function
285276 mp_obj_t init_fn [2 ] = {MP_OBJ_NULL };
286277 struct class_lookup_data lookup = {
@@ -292,19 +283,22 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
292283 };
293284 mp_obj_class_lookup (& lookup , self );
294285
295- mp_obj_t new_ret = MP_OBJ_FROM_PTR (o );
296- if (init_fn [0 ] == MP_OBJ_SENTINEL ) {
297- // Native type's constructor is what wins - it gets all our arguments,
298- // and none Python classes are initialized at all.
286+ const mp_obj_type_t * native_base = NULL ;
287+ mp_obj_instance_t * o ;
288+ if (init_fn [0 ] == MP_OBJ_NULL || init_fn [0 ] == MP_OBJ_SENTINEL ) {
289+ // Either there is no __new__() method defined or there is a native
290+ // constructor. In both cases create a blank instance.
291+ o = mp_obj_new_instance (self , & native_base );
299292
300293 // Since type->make_new() implements both __new__() and __init__() in
301294 // one go, of which the latter may be overridden by the Python subclass,
302295 // we defer (see the end of this function) the call of the native
303296 // constructor to give a chance for the Python __init__() method to call
304297 // said native constructor.
305298
306- } else if (init_fn [0 ] != MP_OBJ_NULL ) {
307- // now call Python class __new__ function with all args
299+ } else {
300+ // Call Python class __new__ function with all args to create an instance
301+ mp_obj_t new_ret ;
308302 if (n_args == 0 && n_kw == 0 ) {
309303 mp_obj_t args2 [1 ] = {MP_OBJ_FROM_PTR (self )};
310304 new_ret = mp_call_function_n_kw (init_fn [0 ], 1 , 0 , args2 );
@@ -316,16 +310,17 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
316310 m_del (mp_obj_t , args2 , 1 + n_args + 2 * n_kw );
317311 }
318312
319- }
313+ // https://docs.python.org/3.4/reference/datamodel.html#object.__new__
314+ // "If __new__() does not return an instance of cls, then the new
315+ // instance's __init__() method will not be invoked."
316+ if (mp_obj_get_type (new_ret ) != self ) {
317+ return new_ret ;
318+ }
320319
321- // https://docs.python.org/3.4/reference/datamodel.html#object.__new__
322- // "If __new__() does not return an instance of cls, then the new instance's __init__() method will not be invoked."
323- if (mp_obj_get_type (new_ret ) != self ) {
324- return new_ret ;
320+ // The instance returned by __new__() becomes the new object
321+ o = MP_OBJ_TO_PTR (new_ret );
325322 }
326323
327- o = MP_OBJ_TO_PTR (new_ret );
328-
329324 // now call Python class __init__ function with all args
330325 // This method has a chance to call super().__init__() to construct a
331326 // possible native base class.
0 commit comments