mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-20 01:08:15 +01:00
[python] Upgrade to micropython 1.11
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2014-2018 Paul Sokolovsky
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -62,7 +63,8 @@ void mp_init(void) {
|
||||
MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;
|
||||
#if MICROPY_ENABLE_SCHEDULER
|
||||
MP_STATE_VM(sched_state) = MP_SCHED_IDLE;
|
||||
MP_STATE_VM(sched_sp) = 0;
|
||||
MP_STATE_VM(sched_idx) = 0;
|
||||
MP_STATE_VM(sched_len) = 0;
|
||||
#endif
|
||||
|
||||
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
||||
@@ -108,12 +110,6 @@ void mp_init(void) {
|
||||
for (size_t i = 0; i < MICROPY_PY_OS_DUPTERM; ++i) {
|
||||
MP_STATE_VM(dupterm_objs[i]) = MP_OBJ_NULL;
|
||||
}
|
||||
MP_STATE_VM(dupterm_arr_obj) = MP_OBJ_NULL;
|
||||
#endif
|
||||
|
||||
#if MICROPY_FSUSERMOUNT
|
||||
// zero out the pointers to the user-mounted devices
|
||||
memset(MP_STATE_VM(fs_user_mount), 0, sizeof(MP_STATE_VM(fs_user_mount)));
|
||||
#endif
|
||||
|
||||
#if MICROPY_VFS
|
||||
@@ -130,11 +126,13 @@ void mp_init(void) {
|
||||
}
|
||||
|
||||
void mp_deinit(void) {
|
||||
MP_THREAD_GIL_EXIT();
|
||||
|
||||
//mp_obj_dict_free(&dict_main);
|
||||
//mp_map_deinit(&MP_STATE_VM(mp_loaded_modules_map));
|
||||
|
||||
// call port specific deinitialization if any
|
||||
#ifdef MICROPY_PORT_INIT_FUNC
|
||||
#ifdef MICROPY_PORT_DEINIT_FUNC
|
||||
MICROPY_PORT_DEINIT_FUNC;
|
||||
#endif
|
||||
}
|
||||
@@ -172,7 +170,7 @@ mp_obj_t mp_load_global(qstr qst) {
|
||||
mp_raise_msg(&mp_type_NameError, "name not defined");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NameError,
|
||||
"name '%q' is not defined", qst));
|
||||
"name '%q' isn't defined", qst));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,7 +219,7 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) {
|
||||
if (op == MP_UNARY_OP_NOT) {
|
||||
// "not x" is the negative of whether "x" is true per Python semantics
|
||||
return mp_obj_new_bool(mp_obj_is_true(arg) == 0);
|
||||
} else if (MP_OBJ_IS_SMALL_INT(arg)) {
|
||||
} else if (mp_obj_is_small_int(arg)) {
|
||||
mp_int_t val = MP_OBJ_SMALL_INT_VALUE(arg);
|
||||
switch (op) {
|
||||
case MP_UNARY_OP_BOOL:
|
||||
@@ -229,6 +227,7 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) {
|
||||
case MP_UNARY_OP_HASH:
|
||||
return arg;
|
||||
case MP_UNARY_OP_POSITIVE:
|
||||
case MP_UNARY_OP_INT:
|
||||
return arg;
|
||||
case MP_UNARY_OP_NEGATIVE:
|
||||
// check for overflow
|
||||
@@ -250,7 +249,7 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) {
|
||||
assert(op == MP_UNARY_OP_INVERT);
|
||||
return MP_OBJ_NEW_SMALL_INT(~val);
|
||||
}
|
||||
} else if (op == MP_UNARY_OP_HASH && MP_OBJ_IS_STR_OR_BYTES(arg)) {
|
||||
} else if (op == MP_UNARY_OP_HASH && mp_obj_is_str_or_bytes(arg)) {
|
||||
// fast path for hashing str/bytes
|
||||
GET_STR_HASH(arg, h);
|
||||
if (h == 0) {
|
||||
@@ -266,12 +265,23 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// With MP_UNARY_OP_INT, mp_unary_op() becomes a fallback for mp_obj_get_int().
|
||||
// In this case provide a more focused error message to not confuse, e.g. chr(1.0)
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_TypeError("unsupported type for operator");
|
||||
if (op == MP_UNARY_OP_INT) {
|
||||
mp_raise_TypeError("can't convert to int");
|
||||
} else {
|
||||
mp_raise_TypeError("unsupported type for operator");
|
||||
}
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"unsupported type for %q: '%s'",
|
||||
mp_unary_op_method_name[op], mp_obj_get_type_str(arg)));
|
||||
if (op == MP_UNARY_OP_INT) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"can't convert %s to int", mp_obj_get_type_str(arg)));
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"unsupported type for %q: '%s'",
|
||||
mp_unary_op_method_name[op], mp_obj_get_type_str(arg)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,7 +329,7 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
} else {
|
||||
return mp_const_false;
|
||||
}
|
||||
} else if (MP_OBJ_IS_TYPE(rhs, &mp_type_tuple)) {
|
||||
} else if (mp_obj_is_type(rhs, &mp_type_tuple)) {
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(rhs);
|
||||
for (size_t i = 0; i < tuple->len; i++) {
|
||||
rhs = tuple->items[i];
|
||||
@@ -335,9 +345,9 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
goto unsupported_op;
|
||||
}
|
||||
|
||||
if (MP_OBJ_IS_SMALL_INT(lhs)) {
|
||||
if (mp_obj_is_small_int(lhs)) {
|
||||
mp_int_t lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs);
|
||||
if (MP_OBJ_IS_SMALL_INT(rhs)) {
|
||||
if (mp_obj_is_small_int(rhs)) {
|
||||
mp_int_t rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs);
|
||||
// This is a binary operation: lhs_val op rhs_val
|
||||
// We need to be careful to handle overflow; see CERT INT32-C
|
||||
@@ -446,8 +456,7 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
case MP_BINARY_OP_INPLACE_POWER:
|
||||
if (rhs_val < 0) {
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
lhs = mp_obj_new_float(lhs_val);
|
||||
goto generic_binary_op;
|
||||
return mp_obj_float_binary_op(op, lhs_val, rhs);
|
||||
#else
|
||||
mp_raise_ValueError("negative power with no float support");
|
||||
#endif
|
||||
@@ -497,11 +506,11 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
default:
|
||||
goto unsupported_op;
|
||||
}
|
||||
// TODO: We just should make mp_obj_new_int() inline and use that
|
||||
// This is an inlined version of mp_obj_new_int, for speed
|
||||
if (MP_SMALL_INT_FITS(lhs_val)) {
|
||||
return MP_OBJ_NEW_SMALL_INT(lhs_val);
|
||||
} else {
|
||||
return mp_obj_new_int(lhs_val);
|
||||
return mp_obj_new_int_from_ll(lhs_val);
|
||||
}
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
} else if (mp_obj_is_float(rhs)) {
|
||||
@@ -512,7 +521,7 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
return res;
|
||||
}
|
||||
#if MICROPY_PY_BUILTINS_COMPLEX
|
||||
} else if (MP_OBJ_IS_TYPE(rhs, &mp_type_complex)) {
|
||||
} else if (mp_obj_is_type(rhs, &mp_type_complex)) {
|
||||
mp_obj_t res = mp_obj_complex_binary_op(op, lhs_val, 0, rhs);
|
||||
if (res == MP_OBJ_NULL) {
|
||||
goto unsupported_op;
|
||||
@@ -582,7 +591,7 @@ unsupported_op:
|
||||
}
|
||||
|
||||
zero_division:
|
||||
mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero");
|
||||
mp_raise_msg(&mp_type_ZeroDivisionError, "divide by zero");
|
||||
}
|
||||
|
||||
mp_obj_t mp_call_function_0(mp_obj_t fun) {
|
||||
@@ -619,7 +628,7 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, cons
|
||||
mp_raise_TypeError("object not callable");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"'%s' object is not callable", mp_obj_get_type_str(fun_in)));
|
||||
"'%s' object isn't callable", mp_obj_get_type_str(fun_in)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,7 +668,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||
|
||||
// Try to get a hint for the size of the kw_dict
|
||||
uint kw_dict_len = 0;
|
||||
if (kw_dict != MP_OBJ_NULL && MP_OBJ_IS_TYPE(kw_dict, &mp_type_dict)) {
|
||||
if (kw_dict != MP_OBJ_NULL && mp_obj_is_type(kw_dict, &mp_type_dict)) {
|
||||
kw_dict_len = mp_obj_dict_len(kw_dict);
|
||||
}
|
||||
|
||||
@@ -681,7 +690,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||
mp_seq_copy(args2 + args2_len, args, n_args, mp_obj_t);
|
||||
args2_len += n_args;
|
||||
|
||||
} else if (MP_OBJ_IS_TYPE(pos_seq, &mp_type_tuple) || MP_OBJ_IS_TYPE(pos_seq, &mp_type_list)) {
|
||||
} else if (mp_obj_is_type(pos_seq, &mp_type_tuple) || mp_obj_is_type(pos_seq, &mp_type_list)) {
|
||||
// optimise the case of a tuple and list
|
||||
|
||||
// get the items
|
||||
@@ -742,15 +751,15 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||
// Note that it can be arbitrary iterator.
|
||||
if (kw_dict == MP_OBJ_NULL) {
|
||||
// pass
|
||||
} else if (MP_OBJ_IS_TYPE(kw_dict, &mp_type_dict)) {
|
||||
} else if (mp_obj_is_type(kw_dict, &mp_type_dict)) {
|
||||
// dictionary
|
||||
mp_map_t *map = mp_obj_dict_get_map(kw_dict);
|
||||
assert(args2_len + 2 * map->used <= args2_alloc); // should have enough, since kw_dict_len is in this case hinted correctly above
|
||||
for (size_t i = 0; i < map->alloc; i++) {
|
||||
if (MP_MAP_SLOT_IS_FILLED(map, i)) {
|
||||
if (mp_map_slot_is_filled(map, i)) {
|
||||
// the key must be a qstr, so intern it if it's a string
|
||||
mp_obj_t key = map->table[i].key;
|
||||
if (!MP_OBJ_IS_QSTR(key)) {
|
||||
if (!mp_obj_is_qstr(key)) {
|
||||
key = mp_obj_str_intern_checked(key);
|
||||
}
|
||||
args2[args2_len++] = key;
|
||||
@@ -780,7 +789,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||
}
|
||||
|
||||
// the key must be a qstr, so intern it if it's a string
|
||||
if (!MP_OBJ_IS_QSTR(key)) {
|
||||
if (!mp_obj_is_qstr(key)) {
|
||||
key = mp_obj_str_intern_checked(key);
|
||||
}
|
||||
|
||||
@@ -815,7 +824,7 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_ob
|
||||
// unpacked items are stored in reverse order into the array pointed to by items
|
||||
void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) {
|
||||
size_t seq_len;
|
||||
if (MP_OBJ_IS_TYPE(seq_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(seq_in, &mp_type_list)) {
|
||||
if (mp_obj_is_type(seq_in, &mp_type_tuple) || mp_obj_is_type(seq_in, &mp_type_list)) {
|
||||
mp_obj_t *seq_items;
|
||||
mp_obj_get_array(seq_in, &seq_len, &seq_items);
|
||||
if (seq_len < num) {
|
||||
@@ -865,9 +874,13 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) {
|
||||
size_t num_right = (num_in >> 8) & 0xff;
|
||||
DEBUG_OP_printf("unpack ex " UINT_FMT " " UINT_FMT "\n", num_left, num_right);
|
||||
size_t seq_len;
|
||||
if (MP_OBJ_IS_TYPE(seq_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(seq_in, &mp_type_list)) {
|
||||
if (mp_obj_is_type(seq_in, &mp_type_tuple) || mp_obj_is_type(seq_in, &mp_type_list)) {
|
||||
// Make the seq variable volatile so the compiler keeps a reference to it,
|
||||
// since if it's a tuple then seq_items points to the interior of the GC cell
|
||||
// and mp_obj_new_list may trigger a GC which doesn't trace this and reclaims seq.
|
||||
volatile mp_obj_t seq = seq_in;
|
||||
mp_obj_t *seq_items;
|
||||
mp_obj_get_array(seq_in, &seq_len, &seq_items);
|
||||
mp_obj_get_array(seq, &seq_len, &seq_items);
|
||||
if (seq_len < num_left + num_right) {
|
||||
goto too_short;
|
||||
}
|
||||
@@ -878,6 +891,7 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) {
|
||||
for (size_t i = 0; i < num_left; i++) {
|
||||
items[num_right + 1 + i] = seq_items[num_left - 1 - i];
|
||||
}
|
||||
seq = MP_OBJ_NULL;
|
||||
} else {
|
||||
// Generic iterable; this gets a bit messy: we unpack known left length to the
|
||||
// items destination array, then the rest to a dynamically created list. Once the
|
||||
@@ -979,10 +993,10 @@ STATIC mp_obj_t mp_obj_new_checked_fun(const mp_obj_type_t *type, mp_obj_t fun)
|
||||
// Conversion means dealing with static/class methods, callables, and values.
|
||||
// see http://docs.python.org/3/howto/descriptor.html
|
||||
void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t member, mp_obj_t *dest) {
|
||||
if (MP_OBJ_IS_TYPE(member, &mp_type_staticmethod)) {
|
||||
if (mp_obj_is_type(member, &mp_type_staticmethod)) {
|
||||
// return just the function
|
||||
dest[0] = ((mp_obj_static_class_method_t*)MP_OBJ_TO_PTR(member))->fun;
|
||||
} else if (MP_OBJ_IS_TYPE(member, &mp_type_classmethod)) {
|
||||
} else if (mp_obj_is_type(member, &mp_type_classmethod)) {
|
||||
// return a bound method, with self being the type of this object
|
||||
// this type should be the type of the original instance, not the base
|
||||
// type (which is what is passed in the 'type' argument to this function)
|
||||
@@ -991,11 +1005,11 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t
|
||||
}
|
||||
dest[0] = ((mp_obj_static_class_method_t*)MP_OBJ_TO_PTR(member))->fun;
|
||||
dest[1] = MP_OBJ_FROM_PTR(type);
|
||||
} else if (MP_OBJ_IS_TYPE(member, &mp_type_type)) {
|
||||
} else if (mp_obj_is_type(member, &mp_type_type)) {
|
||||
// Don't try to bind types (even though they're callable)
|
||||
dest[0] = member;
|
||||
} else if (MP_OBJ_IS_FUN(member)
|
||||
|| (MP_OBJ_IS_OBJ(member)
|
||||
} else if (mp_obj_is_fun(member)
|
||||
|| (mp_obj_is_obj(member)
|
||||
&& (((mp_obj_base_t*)MP_OBJ_TO_PTR(member))->type->name == MP_QSTR_closure
|
||||
|| ((mp_obj_base_t*)MP_OBJ_TO_PTR(member))->type->name == MP_QSTR_generator))) {
|
||||
// only functions, closures and generators objects can be bound to self
|
||||
@@ -1035,14 +1049,13 @@ void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest) {
|
||||
mp_obj_type_t *type = mp_obj_get_type(obj);
|
||||
|
||||
// look for built-in names
|
||||
if (0) {
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
} else if (attr == MP_QSTR___class__) {
|
||||
if (attr == MP_QSTR___class__) {
|
||||
// a.__class__ is equivalent to type(a)
|
||||
dest[0] = MP_OBJ_FROM_PTR(type);
|
||||
} else
|
||||
#endif
|
||||
|
||||
} else if (attr == MP_QSTR___next__ && type->iternext != NULL) {
|
||||
if (attr == MP_QSTR___next__ && type->iternext != NULL) {
|
||||
dest[0] = MP_OBJ_FROM_PTR(&mp_builtin_next_obj);
|
||||
dest[1] = obj;
|
||||
|
||||
@@ -1073,7 +1086,7 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) {
|
||||
mp_raise_msg(&mp_type_AttributeError, "no such attribute");
|
||||
} else {
|
||||
// following CPython, we give a more detailed error message for type objects
|
||||
if (MP_OBJ_IS_TYPE(base, &mp_type_type)) {
|
||||
if (mp_obj_is_type(base, &mp_type_type)) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError,
|
||||
"type object '%q' has no attribute '%q'",
|
||||
((mp_obj_type_t*)MP_OBJ_TO_PTR(base))->name, attr));
|
||||
@@ -1158,7 +1171,7 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
|
||||
mp_raise_TypeError("object not iterable");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"'%s' object is not iterable", mp_obj_get_type_str(o_in)));
|
||||
"'%s' object isn't iterable", mp_obj_get_type_str(o_in)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1180,7 +1193,7 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) {
|
||||
mp_raise_TypeError("object not an iterator");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"'%s' object is not an iterator", mp_obj_get_type_str(o_in)));
|
||||
"'%s' object isn't an iterator", mp_obj_get_type_str(o_in)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1216,7 +1229,7 @@ mp_obj_t mp_iternext(mp_obj_t o_in) {
|
||||
mp_raise_TypeError("object not an iterator");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"'%s' object is not an iterator", mp_obj_get_type_str(o_in)));
|
||||
"'%s' object isn't an iterator", mp_obj_get_type_str(o_in)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1249,15 +1262,8 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th
|
||||
if (send_value == mp_const_none) {
|
||||
mp_load_method_maybe(self_in, MP_QSTR___next__, dest);
|
||||
if (dest[0] != MP_OBJ_NULL) {
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
*ret_val = mp_call_method_n_kw(0, 0, dest);
|
||||
nlr_pop();
|
||||
return MP_VM_RETURN_YIELD;
|
||||
} else {
|
||||
*ret_val = MP_OBJ_FROM_PTR(nlr.ret_val);
|
||||
return MP_VM_RETURN_EXCEPTION;
|
||||
}
|
||||
*ret_val = mp_call_method_n_kw(0, 0, dest);
|
||||
return MP_VM_RETURN_YIELD;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1266,10 +1272,6 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th
|
||||
if (send_value != MP_OBJ_NULL) {
|
||||
mp_load_method(self_in, MP_QSTR_send, dest);
|
||||
dest[2] = send_value;
|
||||
// TODO: This should have exception wrapping like __next__ case
|
||||
// above. Not done right away to think how to optimize native
|
||||
// generators better, see:
|
||||
// https://github.com/micropython/micropython/issues/2628
|
||||
*ret_val = mp_call_method_n_kw(1, 0, dest);
|
||||
return MP_VM_RETURN_YIELD;
|
||||
}
|
||||
@@ -1331,7 +1333,7 @@ mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level) {
|
||||
args[1] = mp_const_none; // TODO should be globals
|
||||
args[2] = mp_const_none; // TODO should be locals
|
||||
args[3] = fromlist;
|
||||
args[4] = level; // must be 0; we don't yet support other values
|
||||
args[4] = level;
|
||||
|
||||
// TODO lookup __import__ and call that instead of going straight to builtin implementation
|
||||
return mp_builtin___import__(5, args);
|
||||
@@ -1373,15 +1375,8 @@ import_error:
|
||||
qstr dot_name_q = qstr_from_strn(dot_name, dot_name_len);
|
||||
mp_local_free(dot_name);
|
||||
|
||||
mp_obj_t args[5];
|
||||
args[0] = MP_OBJ_NEW_QSTR(dot_name_q);
|
||||
args[1] = mp_const_none; // TODO should be globals
|
||||
args[2] = mp_const_none; // TODO should be locals
|
||||
args[3] = mp_const_true; // Pass sentinel "non empty" value to force returning of leaf module
|
||||
args[4] = MP_OBJ_NEW_SMALL_INT(0);
|
||||
|
||||
// TODO lookup __import__ and call that instead of going straight to builtin implementation
|
||||
return mp_builtin___import__(5, args);
|
||||
// For fromlist, pass sentinel "non empty" value to force returning of leaf module
|
||||
return mp_import_name(dot_name_q, mp_const_true, MP_OBJ_NEW_SMALL_INT(0));
|
||||
|
||||
#else
|
||||
|
||||
@@ -1395,12 +1390,16 @@ void mp_import_all(mp_obj_t module) {
|
||||
DEBUG_printf("import all %p\n", module);
|
||||
|
||||
// TODO: Support __all__
|
||||
mp_map_t *map = mp_obj_dict_get_map(MP_OBJ_FROM_PTR(mp_obj_module_get_globals(module)));
|
||||
mp_map_t *map = &mp_obj_module_get_globals(module)->map;
|
||||
for (size_t i = 0; i < map->alloc; i++) {
|
||||
if (MP_MAP_SLOT_IS_FILLED(map, i)) {
|
||||
qstr name = MP_OBJ_QSTR_VALUE(map->table[i].key);
|
||||
if (*qstr_str(name) != '_') {
|
||||
mp_store_name(name, map->table[i].value);
|
||||
if (mp_map_slot_is_filled(map, i)) {
|
||||
// Entry in module global scope may be generated programmatically
|
||||
// (and thus be not a qstr for longer names). Avoid turning it in
|
||||
// qstr if it has '_' and was used exactly to save memory.
|
||||
const char *name = mp_obj_str_get_str(map->table[i].key);
|
||||
if (*name != '_') {
|
||||
qstr qname = mp_obj_str_get_qstr(map->table[i].key);
|
||||
mp_store_name(qname, map->table[i].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user