summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott@tannewt.org>2019-01-14 15:14:40 -0800
committerScott Shawcroft <scott@tannewt.org>2019-01-14 17:29:19 -0800
commit72d993d60c5e5238942491df00776ca31f9758a1 (patch)
tree7dc8ff9548dc5c5fe4286414eb361c61b0774306
parent619bc4caae15ceb7b6de547a5264c9eca9086fe9 (diff)
py changes for supporting superclass constructors that take kwargs
-rw-r--r--extmod/vfs.c2
-rw-r--r--extmod/vfs_fat.c6
-rw-r--r--extmod/vfs_fat_file.c4
-rw-r--r--py/argcheck.c13
-rw-r--r--py/modbuiltins.c2
-rw-r--r--py/obj.h6
-rw-r--r--py/objarray.c12
-rw-r--r--py/objbool.c4
-rw-r--r--py/objcomplex.c4
-rw-r--r--py/objdict.c10
-rw-r--r--py/objenumerate.c4
-rw-r--r--py/objexcept.c14
-rw-r--r--py/objfilter.c4
-rw-r--r--py/objfloat.c4
-rw-r--r--py/objfun.c10
-rw-r--r--py/objint.c4
-rw-r--r--py/objlist.c4
-rw-r--r--py/objmap.c4
-rw-r--r--py/objnamedtuple.c9
-rw-r--r--py/objnamedtuple.h2
-rw-r--r--py/objobject.c4
-rw-r--r--py/objproperty.c4
-rw-r--r--py/objrange.c4
-rw-r--r--py/objreversed.c4
-rw-r--r--py/objset.c8
-rw-r--r--py/objslice.c6
-rw-r--r--py/objstr.c16
-rw-r--r--py/objstr.h2
-rw-r--r--py/objstringio.c4
-rw-r--r--py/objtuple.c4
-rw-r--r--py/objtype.c55
-rw-r--r--py/objtype.h2
-rw-r--r--py/objzip.c4
-rw-r--r--py/runtime.h3
34 files changed, 133 insertions, 109 deletions
diff --git a/extmod/vfs.c b/extmod/vfs.c
index cc794aad5..7d6e6999b 100644
--- a/extmod/vfs.c
+++ b/extmod/vfs.c
@@ -176,7 +176,7 @@ mp_obj_t mp_vfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args
// auto-detect the filesystem and create the corresponding VFS entity.
// (At the moment we only support FAT filesystems.)
#if MICROPY_VFS_FAT
- vfs_obj = mp_fat_vfs_type.make_new(&mp_fat_vfs_type, 1, 0, &vfs_obj);
+ vfs_obj = mp_fat_vfs_type.make_new(&mp_fat_vfs_type, 1, &vfs_obj, NULL);
#endif
}
diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c
index 945ba9e80..95dd6819a 100644
--- a/extmod/vfs_fat.c
+++ b/extmod/vfs_fat.c
@@ -65,8 +65,8 @@ mp_import_stat_t fat_vfs_import_stat(void *vfs_in, const char *path) {
return MP_IMPORT_STAT_NO_EXIST;
}
-STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 1, 1, false);
+STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 1, 1, false);
// create new object
fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t);
@@ -111,7 +111,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_del_obj, fat_vfs_del);
STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) {
// create new object
- fs_user_mount_t *vfs = MP_OBJ_TO_PTR(fat_vfs_make_new(&mp_fat_vfs_type, 1, 0, &bdev_in));
+ fs_user_mount_t *vfs = MP_OBJ_TO_PTR(fat_vfs_make_new(&mp_fat_vfs_type, 1, &bdev_in, NULL));
// make the filesystem
uint8_t working_buf[_MAX_SS];
diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c
index e3eebc9c4..75fa2fbd4 100644
--- a/extmod/vfs_fat_file.c
+++ b/extmod/vfs_fat_file.c
@@ -206,9 +206,9 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar
return MP_OBJ_FROM_PTR(o);
}
-STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
- mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
+ mp_arg_parse_all(n_args, args, kw_args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
return file_open(NULL, type, arg_vals);
}
diff --git a/py/argcheck.c b/py/argcheck.c
index 5cc18d6a2..a8df206e2 100644
--- a/py/argcheck.c
+++ b/py/argcheck.c
@@ -31,13 +31,22 @@
#include "supervisor/shared/translate.h"
-void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) {
+
+void mp_arg_check_num(size_t n_args, mp_map_t *kw_args, size_t n_args_min, size_t n_args_max, bool takes_kw) {
+ size_t n_kw = 0;
+ if (kw_args != NULL) {
+ n_kw = kw_args->used;
+ }
+ mp_arg_check_num_kw_array(n_args, n_kw, n_args_min, n_args_max, takes_kw);
+}
+
+void mp_arg_check_num_kw_array(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) {
// NOTE(tannewt): This prevents this function from being optimized away.
// Without it, functions can crash when reading invalid args.
__asm volatile ("");
// TODO maybe take the function name as an argument so we can print nicer error messages
- if (n_kw && !takes_kw) {
+ if (n_kw > 0 && !takes_kw) {
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
mp_arg_error_terse_mismatch();
#else
diff --git a/py/modbuiltins.c b/py/modbuiltins.c
index fc7ec24c7..e7ce7f998 100644
--- a/py/modbuiltins.c
+++ b/py/modbuiltins.c
@@ -516,7 +516,7 @@ STATIC mp_obj_t mp_builtin_sorted(size_t n_args, const mp_obj_t *args, mp_map_t
if (n_args > 1) {
mp_raise_TypeError(translate("must use keyword argument for key function"));
}
- mp_obj_t self = mp_type_list.make_new(&mp_type_list, 1, 0, args);
+ mp_obj_t self = mp_type_list.make_new(&mp_type_list, 1, args, NULL);
mp_obj_list_sort(1, &self, kwargs);
return self;
diff --git a/py/obj.h b/py/obj.h
index ece3b0ee0..74ce6a0a9 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -432,7 +432,7 @@ typedef struct _mp_obj_iter_buf_t {
#define MP_OBJ_ITER_BUF_NSLOTS ((sizeof(mp_obj_iter_buf_t) + sizeof(mp_obj_t) - 1) / sizeof(mp_obj_t))
typedef void (*mp_print_fun_t)(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind);
-typedef mp_obj_t (*mp_make_new_fun_t)(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
+typedef mp_obj_t (*mp_make_new_fun_t)(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
typedef mp_obj_t (*mp_call_fun_t)(mp_obj_t fun, size_t n_args, size_t n_kw, const mp_obj_t *args);
typedef mp_obj_t (*mp_unary_op_fun_t)(mp_unary_op_t op, mp_obj_t);
typedef mp_obj_t (*mp_binary_op_fun_t)(mp_binary_op_t op, mp_obj_t, mp_obj_t);
@@ -671,7 +671,7 @@ mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items);
mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in);
const char *mp_obj_get_type_str(mp_const_obj_t o_in);
bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo); // arguments should be type objects
-mp_obj_t mp_instance_cast_to_native_base(mp_const_obj_t self_in, mp_const_obj_t native_type);
+mp_obj_t mp_instance_cast_to_native_base(mp_obj_t self_in, mp_const_obj_t native_type);
void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind);
void mp_obj_print(mp_obj_t o, mp_print_kind_t kind);
@@ -720,7 +720,7 @@ void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qs
void mp_obj_exception_get_traceback(mp_obj_t self_in, size_t *n, size_t **values);
mp_obj_t mp_obj_exception_get_traceback_obj(mp_obj_t self_in);
mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in);
-mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
+mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in);
void mp_init_emergency_exception_buf(void);
diff --git a/py/objarray.c b/py/objarray.c
index 0c8c7d855..9114a63c5 100644
--- a/py/objarray.c
+++ b/py/objarray.c
@@ -157,9 +157,9 @@ STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) {
#endif
#if MICROPY_PY_ARRAY
-STATIC mp_obj_t array_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t array_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
- mp_arg_check_num(n_args, n_kw, 1, 2, false);
+ mp_arg_check_num(n_args, kw_args, 1, 2, false);
// get typecode
const char *typecode = mp_obj_str_get_str(args[0]);
@@ -175,9 +175,9 @@ STATIC mp_obj_t array_make_new(const mp_obj_type_t *type_in, size_t n_args, size
#endif
#if MICROPY_PY_BUILTINS_BYTEARRAY
-STATIC mp_obj_t bytearray_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t bytearray_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
- mp_arg_check_num(n_args, n_kw, 0, 1, false);
+ mp_arg_check_num(n_args, kw_args, 0, 1, false);
if (n_args == 0) {
// no args: construct an empty bytearray
@@ -207,13 +207,13 @@ mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items) {
return MP_OBJ_FROM_PTR(self);
}
-STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
// TODO possibly allow memoryview constructor to take start/stop so that one
// can do memoryview(b, 4, 8) instead of memoryview(b)[4:8] (uses less RAM)
- mp_arg_check_num(n_args, n_kw, 1, 1, false);
+ mp_arg_check_num(n_args, kw_args, 1, 1, false);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ);
diff --git a/py/objbool.c b/py/objbool.c
index 5755b188e..cd7d7100c 100644
--- a/py/objbool.c
+++ b/py/objbool.c
@@ -50,9 +50,9 @@ STATIC void bool_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_
}
}
-STATIC mp_obj_t bool_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t bool_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
- mp_arg_check_num(n_args, n_kw, 0, 1, false);
+ mp_arg_check_num(n_args, kw_args, 0, 1, false);
if (n_args == 0) {
return mp_const_false;
diff --git a/py/objcomplex.c b/py/objcomplex.c
index 3336d7b05..b38e2c5fa 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -75,9 +75,9 @@ STATIC void complex_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_
}
}
-STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
- mp_arg_check_num(n_args, n_kw, 0, 2, false);
+ mp_arg_check_num(n_args, kw_args, 0, 2, false);
switch (n_args) {
case 0:
diff --git a/py/objdict.c b/py/objdict.c
index cd110f1c1..f672ac039 100644
--- a/py/objdict.c
+++ b/py/objdict.c
@@ -81,7 +81,7 @@ STATIC void dict_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_
}
}
-STATIC mp_obj_t dict_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t dict_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
mp_obj_t dict_out = mp_obj_new_dict(0);
mp_obj_dict_t *dict = MP_OBJ_TO_PTR(dict_out);
dict->base.type = type;
@@ -90,11 +90,9 @@ STATIC mp_obj_t dict_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
dict->map.is_ordered = 1;
}
#endif
- if (n_args > 0 || n_kw > 0) {
+ if (n_args > 0 || kw_args != NULL) {
mp_obj_t args2[2] = {dict_out, args[0]}; // args[0] is always valid, even if it's not a positional arg
- mp_map_t kwargs;
- mp_map_init_fixed_table(&kwargs, n_kw, args + n_args);
- dict_update(n_args + 1, args2, &kwargs); // dict_update will check that n_args + 1 == 1 or 2
+ dict_update(n_args + 1, args2, kw_args); // dict_update will check that n_args + 1 == 1 or 2
}
return dict_out;
}
@@ -328,7 +326,7 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg
mp_obj_dict_t *self = MP_OBJ_TO_PTR(args[0]);
mp_ensure_not_fixed(self);
- mp_arg_check_num(n_args, kwargs->used, 1, 2, true);
+ mp_arg_check_num(n_args, kwargs, 1, 2, true);
if (n_args == 2) {
// given a positional argument
diff --git a/py/objenumerate.c b/py/objenumerate.c
index 1a9d30f83..4919a9b8f 100644
--- a/py/objenumerate.c
+++ b/py/objenumerate.c
@@ -39,7 +39,7 @@ typedef struct _mp_obj_enumerate_t {
STATIC mp_obj_t enumerate_iternext(mp_obj_t self_in);
-STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
#if MICROPY_CPYTHON_COMPAT
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_iterable, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
@@ -50,7 +50,7 @@ STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, siz
struct {
mp_arg_val_t iterable, start;
} arg_vals;
- mp_arg_parse_all_kw_array(n_args, n_kw, args,
+ mp_arg_parse_all(n_args, args, kw_args,
MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&arg_vals);
// create enumerate object
diff --git a/py/objexcept.c b/py/objexcept.c
index c54e5fd4a..0e9255db7 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -130,8 +130,8 @@ void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin
mp_obj_tuple_print(print, MP_OBJ_FROM_PTR(o->args), kind);
}
-mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false);
+mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 0, MP_OBJ_FUN_ARGS_MAX, false);
// Try to allocate memory for the exception, with fallback to emergency exception object
mp_obj_exception_t *o_exc = m_new_obj_maybe(mp_obj_exception_t);
@@ -336,7 +336,7 @@ mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg)
mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, const mp_obj_t *args) {
assert(exc_type->make_new == mp_obj_exception_make_new);
- return exc_type->make_new(exc_type, n_args, 0, args);
+ return exc_type->make_new(exc_type, n_args, args, NULL);
}
mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg) {
@@ -438,7 +438,7 @@ mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const com
o_str->base.type = &mp_type_str;
o_str->hash = qstr_compute_hash(o_str->data, o_str->len);
mp_obj_t arg = MP_OBJ_FROM_PTR(o_str);
- return mp_obj_exception_make_new(exc_type, 1, 0, &arg);
+ return mp_obj_exception_make_new(exc_type, 1, &arg, NULL);
}
// return true if the given object is an exception type
@@ -607,7 +607,7 @@ STATIC mp_obj_t code_make_new(qstr file, qstr block) {
mp_obj_new_bytearray(0, NULL), // co_lnotab
};
- return namedtuple_make_new((const mp_obj_type_t*)&code_type_obj, 15, 0, elems);
+ return namedtuple_make_new((const mp_obj_type_t*)&code_type_obj, 15, elems, NULL);
}
STATIC const mp_obj_namedtuple_type_t frame_type_obj = {
@@ -650,7 +650,7 @@ STATIC mp_obj_t frame_make_new(mp_obj_t f_code, int f_lineno) {
mp_const_none, // f_trace
};
- return namedtuple_make_new((const mp_obj_type_t*)&frame_type_obj, 8, 0, elems);
+ return namedtuple_make_new((const mp_obj_type_t*)&frame_type_obj, 8, elems, NULL);
}
STATIC const mp_obj_namedtuple_type_t traceback_type_obj = {
@@ -687,7 +687,7 @@ STATIC mp_obj_t traceback_from_values(size_t *values, mp_obj_t tb_next) {
tb_next,
};
- return namedtuple_make_new((const mp_obj_type_t*)&traceback_type_obj, 4, 0, elems);
+ return namedtuple_make_new((const mp_obj_type_t*)&traceback_type_obj, 4, elems, NULL);
};
mp_obj_t mp_obj_exception_get_traceback_obj(mp_obj_t self_in) {
diff --git a/py/objfilter.c b/py/objfilter.c
index cb965d8c3..af95326e6 100644
--- a/py/objfilter.c
+++ b/py/objfilter.c
@@ -34,8 +34,8 @@ typedef struct _mp_obj_filter_t {
mp_obj_t iter;
} mp_obj_filter_t;
-STATIC mp_obj_t filter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 2, 2, false);
+STATIC mp_obj_t filter_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 2, 2, false);
mp_obj_filter_t *o = m_new_obj(mp_obj_filter_t);
o->base.type = type;
o->fun = args[0];
diff --git a/py/objfloat.c b/py/objfloat.c
index c3f47018c..f544ade05 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -133,9 +133,9 @@ STATIC void float_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t
}
}
-STATIC mp_obj_t float_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t float_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
- mp_arg_check_num(n_args, n_kw, 0, 1, false);
+ mp_arg_check_num(n_args, kw_args, 0, 1, false);
switch (n_args) {
case 0:
diff --git a/py/objfun.c b/py/objfun.c
index 8c51d92e0..2ada0b3f1 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -52,7 +52,7 @@ STATIC mp_obj_t fun_builtin_0_call(mp_obj_t self_in, size_t n_args, size_t n_kw,
(void)args;
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_0));
mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in);
- mp_arg_check_num(n_args, n_kw, 0, 0, false);
+ mp_arg_check_num_kw_array(n_args, n_kw, 0, 0, false);
return self->fun._0();
}
@@ -66,7 +66,7 @@ const mp_obj_type_t mp_type_fun_builtin_0 = {
STATIC mp_obj_t fun_builtin_1_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_1));
mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in);
- mp_arg_check_num(n_args, n_kw, 1, 1, false);
+ mp_arg_check_num_kw_array(n_args, n_kw, 1, 1, false);
return self->fun._1(args[0]);
}
@@ -80,7 +80,7 @@ const mp_obj_type_t mp_type_fun_builtin_1 = {
STATIC mp_obj_t fun_builtin_2_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_2));
mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in);
- mp_arg_check_num(n_args, n_kw, 2, 2, false);
+ mp_arg_check_num_kw_array(n_args, n_kw, 2, 2, false);
return self->fun._2(args[0], args[1]);
}
@@ -94,7 +94,7 @@ const mp_obj_type_t mp_type_fun_builtin_2 = {
STATIC mp_obj_t fun_builtin_3_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_3));
mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in);
- mp_arg_check_num(n_args, n_kw, 3, 3, false);
+ mp_arg_check_num_kw_array(n_args, n_kw, 3, 3, false);
return self->fun._3(args[0], args[1], args[2]);
}
@@ -110,7 +110,7 @@ STATIC mp_obj_t fun_builtin_var_call(mp_obj_t self_in, size_t n_args, size_t n_k
mp_obj_fun_builtin_var_t *self = MP_OBJ_TO_PTR(self_in);
// check number of arguments
- mp_arg_check_num(n_args, n_kw, self->n_args_min, self->n_args_max, self->is_kw);
+ mp_arg_check_num_kw_array(n_args, n_kw, self->n_args_min, self->n_args_max, self->is_kw);
if (self->is_kw) {
// function allows keywords
diff --git a/py/objint.c b/py/objint.c
index 2ac370d17..fd746d331 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -42,9 +42,9 @@
#endif
// This dispatcher function is expected to be independent of the implementation of long int
-STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
- mp_arg_check_num(n_args, n_kw, 0, 2, false);
+ mp_arg_check_num(n_args, kw_args, 0, 2, false);
switch (n_args) {
case 0:
diff --git a/py/objlist.c b/py/objlist.c
index d4f9b0222..67940e44c 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -68,9 +68,9 @@ STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) {
return list;
}
-STATIC mp_obj_t list_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t list_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
- mp_arg_check_num(n_args, n_kw, 0, 1, false);
+ mp_arg_check_num(n_args, kw_args, 0, 1, false);
switch (n_args) {
case 0:
diff --git a/py/objmap.c b/py/objmap.c
index 908c61507..cf71f99ee 100644
--- a/py/objmap.c
+++ b/py/objmap.c
@@ -36,8 +36,8 @@ typedef struct _mp_obj_map_t {
mp_obj_t iters[];
} mp_obj_map_t;
-STATIC mp_obj_t map_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 2, MP_OBJ_FUN_ARGS_MAX, false);
+STATIC mp_obj_t map_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 2, MP_OBJ_FUN_ARGS_MAX, false);
mp_obj_map_t *o = m_new_obj_var(mp_obj_map_t, mp_obj_t, n_args - 1);
o->base.type = type;
o->n_iters = n_args - 1;
diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c
index 800991c43..781a1871b 100644
--- a/py/objnamedtuple.c
+++ b/py/objnamedtuple.c
@@ -93,9 +93,10 @@ void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
}
}
-mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
const mp_obj_namedtuple_type_t *type = (const mp_obj_namedtuple_type_t*)type_in;
size_t num_fields = type->n_fields;
+ size_t n_kw = kw_args->used;
if (n_args + n_kw != num_fields) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
mp_arg_error_terse_mismatch();
@@ -119,8 +120,8 @@ mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t
// Fill in the remaining slots with the keyword args
memset(&tuple->items[n_args], 0, sizeof(mp_obj_t) * n_kw);
- for (size_t i = n_args; i < n_args + 2 * n_kw; i += 2) {
- qstr kw = mp_obj_str_get_qstr(args[i]);
+ for (size_t i = 0; i < n_kw; i++) {
+ qstr kw = mp_obj_str_get_qstr(kw_args->table[i].key);
size_t id = mp_obj_namedtuple_find_field(type, kw);
if (id == (size_t)-1) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
@@ -138,7 +139,7 @@ mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t
translate("function got multiple values for argument '%q'"), kw);
}
}
- tuple->items[id] = args[i + 1];
+ tuple->items[id] = kw_args->table[i].value;
}
return MP_OBJ_FROM_PTR(tuple);
diff --git a/py/objnamedtuple.h b/py/objnamedtuple.h
index deac7107b..0ea0d2862 100644
--- a/py/objnamedtuple.h
+++ b/py/objnamedtuple.h
@@ -51,7 +51,7 @@ void namedtuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t ki
size_t mp_obj_namedtuple_find_field(const mp_obj_namedtuple_type_t *type, qstr name);
void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest);
mp_obj_namedtuple_type_t *mp_obj_new_namedtuple_base(size_t n_fields, mp_obj_t *fields);
-mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
+mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
#endif // MICROPY_PY_COLLECTIONS
diff --git a/py/objobject.c b/py/objobject.c
index fa8c29cff..a42edde3c 100644
--- a/py/objobject.c
+++ b/py/objobject.c
@@ -35,9 +35,9 @@ typedef struct _mp_obj_object_t {
mp_obj_base_t base;
} mp_obj_object_t;
-STATIC mp_obj_t object_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t object_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)args;
- mp_arg_check_num(n_args, n_kw, 0, 0, false);
+ mp_arg_check_num(n_args, kw_args, 0, 0, false);
mp_obj_object_t *o = m_new_obj(mp_obj_object_t);
o->base.type = type;
return MP_OBJ_FROM_PTR(o);
diff --git a/py/objproperty.c b/py/objproperty.c
index 4aba6c7a1..ddf484af2 100644
--- a/py/objproperty.c
+++ b/py/objproperty.c
@@ -33,7 +33,7 @@
#if MICROPY_PY_BUILTINS_PROPERTY
-STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
enum { ARG_fget, ARG_fset, ARG_fdel, ARG_doc };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
@@ -42,7 +42,7 @@ STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, size
{ MP_QSTR_doc, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
};
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
+ mp_arg_parse_all(n_args, args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
mp_obj_property_t *o = m_new_obj(mp_obj_property_t);
o->base.type = type;
diff --git a/py/objrange.c b/py/objrange.c
index 33c0d9b11..30d55c56c 100644
--- a/py/objrange.c
+++ b/py/objrange.c
@@ -91,8 +91,8 @@ STATIC void range_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind
}
}
-STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 1, 3, false);
+STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 1, 3, false);
mp_obj_range_t *o = m_new_obj(mp_obj_range_t);
o->base.type = type;
diff --git a/py/objreversed.c b/py/objreversed.c
index e498b553d..4937d0818 100644
--- a/py/objreversed.c
+++ b/py/objreversed.c
@@ -37,8 +37,8 @@ typedef struct _mp_obj_reversed_t {
mp_uint_t cur_index; // current index, plus 1; 0=no more, 1=last one (index 0)
} mp_obj_reversed_t;
-STATIC mp_obj_t reversed_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 1, 1, false);
+STATIC mp_obj_t reversed_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 1, 1, false);
// check if __reversed__ exists, and if so delegate to it
mp_obj_t dest[2];
diff --git a/py/objset.c b/py/objset.c
index 00d6eae0e..5d1608c7e 100644
--- a/py/objset.c
+++ b/py/objset.c
@@ -103,8 +103,8 @@ STATIC void set_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
#endif
}
-STATIC mp_obj_t set_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 0, 1, false);
+STATIC mp_obj_t set_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 0, 1, false);
switch (n_args) {
case 0: {
@@ -299,7 +299,7 @@ STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool
if (is_set_or_frozenset(self_in)) {
self = MP_OBJ_TO_PTR(self_in);
} else {
- self = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, 0, &self_in));
+ self = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, &self_in, NULL));
cleanup_self = true;
}
@@ -308,7 +308,7 @@ STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool
if (is_set_or_frozenset(other_in)) {
other = MP_OBJ_TO_PTR(other_in);
} else {
- other = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, 0, &other_in));
+ other = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, &other_in, NULL));
cleanup_other = true;
}
mp_obj_t out = mp_const_true;
diff --git a/py/objslice.c b/py/objslice.c
index 08f18935b..5a15be55a 100644
--- a/py/objslice.c
+++ b/py/objslice.c
@@ -130,7 +130,7 @@ STATIC void slice_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
}
STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type,
- size_t n_args, size_t n_kw, const mp_obj_t *args);
+ size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
#endif
const mp_obj_type_t mp_type_slice = {
@@ -154,12 +154,12 @@ mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) {
#if MICROPY_PY_BUILTINS_SLICE_ATTRS
STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type,
- size_t n_args, size_t n_kw, const mp_obj_t *args) {
+ size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
if (type != &mp_type_slice) {
mp_raise_NotImplementedError(translate("Cannot subclass slice"));
}
// check number of arguments
- mp_arg_check_num(n_args, n_kw, 1, 3, false);
+ mp_arg_check_num(n_args, kw_args, 1, 3, false);
// 1st argument is the pin
mp_obj_t start = mp_const_none;
diff --git a/py/objstr.c b/py/objstr.c
index 621f1b837..637323f4c 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -132,14 +132,14 @@ STATIC void str_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
}
}
-mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
#if MICROPY_CPYTHON_COMPAT
- if (n_kw != 0) {
+ if (kw_args != NULL && kw_args->used != 0) {
mp_arg_error_unimpl_kw();
}
#endif
- mp_arg_check_num(n_args, n_kw, 0, 3, false);
+ mp_arg_check_num(n_args, kw_args, 0, 3, false);
switch (n_args) {
case 0:
@@ -190,11 +190,11 @@ mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
}
}
-STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
#if MICROPY_CPYTHON_COMPAT
- if (n_kw != 0) {
+ if (kw_args != NULL && kw_args->used != 0) {
mp_arg_error_unimpl_kw();
}
#else
@@ -455,7 +455,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
if (!MP_OBJ_IS_TYPE(arg, &mp_type_list) && !MP_OBJ_IS_TYPE(arg, &mp_type_tuple)) {
// arg is not a list nor a tuple, try to convert it to a list
// TODO: Try to optimize?
- arg = mp_type_list.make_new(&mp_type_list, 1, 0, &arg);
+ arg = mp_type_list.make_new(&mp_type_list, 1, &arg, NULL);
}
mp_obj_get_array(arg, &seq_len, &seq_items);
@@ -1875,7 +1875,7 @@ STATIC mp_obj_t bytes_decode(size_t n_args, const mp_obj_t *args) {
args = new_args;
n_args++;
}
- return mp_obj_str_make_new(&mp_type_str, n_args, 0, args);
+ return mp_obj_str_make_new(&mp_type_str, n_args, args, NULL);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_decode_obj, 1, 3, bytes_decode);
@@ -1888,7 +1888,7 @@ STATIC mp_obj_t str_encode(size_t n_args, const mp_obj_t *args) {
args = new_args;
n_args++;
}
- return bytes_make_new(NULL, n_args, 0, args);
+ return bytes_make_new(NULL, n_args, args, NULL);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj, 1, 3, str_encode);
#endif
diff --git a/py/objstr.h b/py/objstr.h
index 4e55cad09..895130446 100644
--- a/py/objstr.h
+++ b/py/objstr.h
@@ -61,7 +61,7 @@ const byte *mp_obj_str_get_data_no_check(mp_obj_t self_in, size_t *len);
else { str_len = ((mp_obj_str_t*)MP_OBJ_TO_PTR(str_obj_in))->len; str_data = ((mp_obj_str_t*)MP_OBJ_TO_PTR(str_obj_in))->data; }
#endif
-mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
+mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
void mp_str_print_json(const mp_print_t *print, const byte *str_data, size_t str_len);
mp_obj_t mp_obj_str_format(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs);
mp_obj_t mp_obj_str_split(size_t n_args, const mp_obj_t *args);
diff --git a/py/objstringio.c b/py/objstringio.c
index d21248ad7..d2ca6decd 100644
--- a/py/objstringio.c
+++ b/py/objstringio.c
@@ -186,8 +186,8 @@ STATIC mp_obj_stringio_t *stringio_new(const mp_obj_type_t *type) {
return o;
}
-STATIC mp_obj_t stringio_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- (void)n_kw; // TODO check n_kw==0
+STATIC mp_obj_t stringio_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ (void)kw_args; // TODO check kw_args->used == 0
mp_uint_t sz = 16;
bool initdata = false;
diff --git a/py/objtuple.c b/py/objtuple.c
index b4f5b1bdf..d3262cebd 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -59,10 +59,10 @@ void mp_obj_tuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t
}
}
-STATIC mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
- mp_arg_check_num(n_args, n_kw, 0, 1, false);
+ mp_arg_check_num(n_args, kw_args, 0, 1, false);
switch (n_args) {
case 0:
diff --git a/py/objtype.c b/py/objtype.c
index 95dfc2a15..f7fe3b3f6 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -50,7 +50,7 @@
#define TYPE_FLAG_IS_SUBCLASSED (0x0001)
#define TYPE_FLAG_HAS_SPECIAL_ACCESSORS (0x0002)
-STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
+STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
/******************************************************************************/
// instance object
@@ -90,14 +90,14 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t
// This wrapper function is allows a subclass of a native type to call the
// __init__() method (corresponding to type->make_new) of the native type.
-STATIC mp_obj_t native_base_init_wrapper(size_t n_args, const mp_obj_t *args) {
- mp_obj_instance_t *self = MP_OBJ_TO_PTR(args[0]);
+STATIC mp_obj_t native_base_init_wrapper(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ mp_obj_instance_t *self = MP_OBJ_TO_PTR(pos_args[0]);
const mp_obj_type_t *native_base = NULL;
instance_count_native_bases(self->base.type, &native_base);
- self->subobj[0] = native_base->make_new(native_base, n_args - 1, 0, args + 1);
+ self->subobj[0] = native_base->make_new(native_base, n_args - 1, pos_args + 1, kw_args);
return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(native_base_init_wrapper_obj, 1, MP_OBJ_FUN_ARGS_MAX, native_base_init_wrapper);
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(native_base_init_wrapper_obj, 1, native_base_init_wrapper);
#if !MICROPY_CPYTHON_COMPAT
STATIC
@@ -281,7 +281,7 @@ STATIC void instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
mp_printf(print, "<%s object at %p>", mp_obj_get_type_str(self_in), self);
}
-mp_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) {
+mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
assert(mp_obj_is_instance_type(self));
// look for __new__ function
@@ -297,6 +297,10 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
const mp_obj_type_t *native_base = NULL;
mp_obj_instance_t *o;
+ size_t n_kw = 0;
+ if (kw_args != 0) {
+ n_kw = kw_args->used;
+ }
if (init_fn[0] == MP_OBJ_NULL || init_fn[0] == MP_OBJ_SENTINEL) {
// Either there is no __new__() method defined or there is a native
// constructor. In both cases create a blank instance.
@@ -315,9 +319,12 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
mp_obj_t args2[1] = {MP_OBJ_FROM_PTR(self)};
new_ret = mp_call_function_n_kw(init_fn[0], 1, 0, args2);
} else {
+ // TODO(tannewt): Could this be on the stack? It's deleted below.
mp_obj_t *args2 = m_new(mp_obj_t, 1 + n_args + 2 * n_kw);
args2[0] = MP_OBJ_FROM_PTR(self);
- memcpy(args2 + 1, args, (n_args + 2 * n_kw) * sizeof(mp_obj_t));
+ memcpy(args2 + 1, args, n_args * sizeof(mp_obj_t));
+ // copy in kwargs
+ memcpy(args2 + 1 + n_args, kw_args->table, 2 * n_kw * sizeof(mp_obj_t));
new_ret = mp_call_function_n_kw(init_fn[0], n_args + 1, n_kw, args2);
m_del(mp_obj_t, args2, 1 + n_args + 2 * n_kw);
}
@@ -343,13 +350,16 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
mp_obj_class_lookup(&lookup, self);
if (init_fn[0] != MP_OBJ_NULL) {
mp_obj_t init_ret;
- if (n_args == 0 && n_kw == 0) {
+ if (n_args == 0 && kw_args == NULL) {
init_ret = mp_call_method_n_kw(0, 0, init_fn);
} else {
+ // TODO(tannewt): Could this be on the stack? It's deleted below.
mp_obj_t *args2 = m_new(mp_obj_t, 2 + n_args + 2 * n_kw);
args2[0] = init_fn[0];
args2[1] = init_fn[1];
- memcpy(args2 + 2, args, (n_args + 2 * n_kw) * sizeof(mp_obj_t));
+ // copy in kwargs
+ memcpy(args2 + 2, args, n_args * sizeof(mp_obj_t));
+ memcpy(args2 + 2 + n_args, kw_args->table, 2 * n_kw * sizeof(mp_obj_t));
init_ret = mp_call_method_n_kw(n_args, n_kw, args2);
m_del(mp_obj_t, args2, 2 + n_args + 2 * n_kw);
}
@@ -367,7 +377,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
// If the type had a native base that was not explicitly initialised
// (constructed) by the Python __init__() method then construct it now.
if (native_base != NULL && o->subobj[0] == MP_OBJ_FROM_PTR(&native_base_init_wrapper_obj)) {
- o->subobj[0] = native_base->make_new(native_base, n_args, n_kw, args);
+ o->subobj[0] = native_base->make_new(native_base, n_args, args, kw_args);
}
return MP_OBJ_FROM_PTR(o);
@@ -959,10 +969,10 @@ STATIC void type_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_
mp_printf(print, "<class '%q'>", self->name);
}
-STATIC mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
- mp_arg_check_num(n_args, n_kw, 1, 3, false);
+ mp_arg_check_num(n_args, kw_args, 1, 3, false);
switch (n_args) {
case 1:
@@ -992,8 +1002,10 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp
}
}
- // make new instance
- mp_obj_t o = self->make_new(self, n_args, n_kw, args);
+ // create a map directly from the given args array and make a new instance
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
+ mp_obj_t o = self->make_new(self, n_args, args, &kw_args);
// return new instance
return o;
@@ -1170,7 +1182,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
// __new__ slot exists; check if it is a function
if (MP_OBJ_IS_FUN(elem->value)) {
// __new__ is a function, wrap it in a staticmethod decorator
- elem->value = static_class_method_make_new(&mp_type_staticmethod, 1, 0, &elem->value);
+ elem->value = static_class_method_make_new(&mp_type_staticmethod, 1, &elem->value, NULL);
}
}
@@ -1196,11 +1208,11 @@ STATIC void super_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind
mp_print_str(print, ">");
}
-STATIC mp_obj_t super_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t super_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
// 0 arguments are turned into 2 in the compiler
// 1 argument is not yet implemented
- mp_arg_check_num(n_args, n_kw, 2, 2, false);
+ mp_arg_check_num(n_args, kw_args, 2, 2, false);
if(!MP_OBJ_IS_TYPE(args[0], &mp_type_type)) {
mp_raise_TypeError(translate("first argument to super() must be type"));
}
@@ -1394,11 +1406,14 @@ STATIC mp_obj_t mp_builtin_isinstance(mp_obj_t object, mp_obj_t classinfo) {
MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_isinstance_obj, mp_builtin_isinstance);
-mp_obj_t mp_instance_cast_to_native_base(mp_const_obj_t self_in, mp_const_obj_t native_type) {
+mp_obj_t mp_instance_cast_to_native_base(mp_obj_t self_in, mp_const_obj_t native_type) {
mp_obj_type_t *self_type = mp_obj_get_type(self_in);
if (!mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(self_type), native_type)) {
return MP_OBJ_NULL;
}
+ if (MP_OBJ_FROM_PTR(self_type) == native_type) {
+ return self_in;
+ }
mp_obj_instance_t *self = (mp_obj_instance_t*)MP_OBJ_TO_PTR(self_in);
return self->subobj[0];
}
@@ -1406,10 +1421,10 @@ mp_obj_t mp_instance_cast_to_native_base(mp_const_obj_t self_in, mp_const_obj_t
/******************************************************************************/
// staticmethod and classmethod types (probably should go in a different file)
-STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
assert(self == &mp_type_staticmethod || self == &mp_type_classmethod);
- mp_arg_check_num(n_args, n_kw, 1, 1, false);
+ mp_arg_check_num(n_args, kw_args, 1, 1, false);
mp_obj_static_class_method_t *o = m_new_obj(mp_obj_static_class_method_t);
*o = (mp_obj_static_class_method_t){{self}, args[0]};
diff --git a/py/objtype.h b/py/objtype.h
index 3fc8c6e1b..13613f01f 100644
--- a/py/objtype.h
+++ b/py/objtype.h
@@ -49,6 +49,6 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons
#define mp_obj_is_instance_type(type) ((type)->make_new == mp_obj_instance_make_new)
#define mp_obj_is_native_type(type) ((type)->make_new != mp_obj_instance_make_new)
// this needs to be exposed for the above macros to work correctly
-mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
+mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
#endif // MICROPY_INCLUDED_PY_OBJTYPE_H
diff --git a/py/objzip.c b/py/objzip.c
index 0183925e3..ce9afd55d 100644
--- a/py/objzip.c
+++ b/py/objzip.c
@@ -36,8 +36,8 @@ typedef struct _mp_obj_zip_t {
mp_obj_t iters[];
} mp_obj_zip_t;
-STATIC mp_obj_t zip_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false);
+STATIC mp_obj_t zip_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 0, MP_OBJ_FUN_ARGS_MAX, false);
mp_obj_zip_t *o = m_new_obj_var(mp_obj_zip_t, mp_obj_t, n_args);
o->base.type = type;
diff --git a/py/runtime.h b/py/runtime.h
index ece226e7a..e52d3232e 100644
--- a/py/runtime.h
+++ b/py/runtime.h
@@ -77,8 +77,9 @@ bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg);
// extra printing method specifically for mp_obj_t's which are integral type
int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char, int flags, char fill, int width, int prec);
-void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw);
+void mp_arg_check_num(size_t n_args, mp_map_t *kw_args, size_t n_args_min, size_t n_args_max, bool takes_kw);
void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals);
+void mp_arg_check_num_kw_array(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw);
void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals);
NORETURN void mp_arg_error_terse_mismatch(void);
NORETURN void mp_arg_error_unimpl_kw(void);