Skip to content

1.13 test fixes #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
May 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions examples/natmod/features0/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Location of top-level MicroPython directory
MPY_DIR = ../../..

# Name of module
MOD = features0

# Source files (.c or .py)
SRC = features0.c

# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
ARCH = x64

# Include to get the rules for compiling and linking the module
include $(MPY_DIR)/py/dynruntime.mk
40 changes: 40 additions & 0 deletions examples/natmod/features0/features0.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* This example demonstrates the following features in a native module:
- defining a simple function exposed to Python
- defining a local, helper C function
- getting and creating integer objects
*/

// Include the header file to get access to the MicroPython API
#include "py/dynruntime.h"

// Helper function to compute factorial
STATIC mp_int_t factorial_helper(mp_int_t x) {
if (x == 0) {
return 1;
}
return x * factorial_helper(x - 1);
}

// This is the function which will be called from Python, as factorial(x)
STATIC mp_obj_t factorial(mp_obj_t x_obj) {
// Extract the integer from the MicroPython input object
mp_int_t x = mp_obj_get_int(x_obj);
// Calculate the factorial
mp_int_t result = factorial_helper(x);
// Convert the result to a MicroPython integer object and return it
return mp_obj_new_int(result);
}
// Define a Python reference to the function above
STATIC MP_DEFINE_CONST_FUN_OBJ_1(factorial_obj, factorial);

// This is the entry point and is called when the module is imported
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
// This must be first, it sets up the globals dict and other things
MP_DYNRUNTIME_INIT_ENTRY

// Make the function available in the module's namespace
mp_store_global(MP_QSTR_factorial, MP_OBJ_FROM_PTR(&factorial_obj));

// This must be last, it restores the globals dict
MP_DYNRUNTIME_INIT_EXIT
}
3 changes: 3 additions & 0 deletions extmod/modframebuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ STATIC const mp_obj_type_t mp_type_framebuf;
static mp_obj_framebuf_t *native_framebuf(mp_obj_t framebuf_obj) {
mp_obj_t native_framebuf = mp_obj_cast_to_native_base(framebuf_obj, &mp_type_framebuf);
mp_obj_assert_native_inited(native_framebuf);
if (native_framebuf == MP_OBJ_NULL) {
mp_raise_TypeError(NULL);
}
return MP_OBJ_TO_PTR(native_framebuf);
}

Expand Down
47 changes: 11 additions & 36 deletions extmod/modure.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,13 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_split_obj, 2, 3, re_split);

#if MICROPY_PY_URE_SUB

STATIC mp_obj_t re_sub_helper(mp_obj_t self_in, size_t n_args, const mp_obj_t *args) {
mp_obj_re_t *self = MP_OBJ_TO_PTR(self_in);
STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) {
mp_obj_re_t *self;
if (mp_obj_is_type(args[0], &re_type)) {
self = MP_OBJ_TO_PTR(args[0]);
} else {
self = MP_OBJ_TO_PTR(mod_re_compile(1, args));
}
mp_obj_t replace = args[1];
mp_obj_t where = args[2];
mp_int_t count = 0;
Expand Down Expand Up @@ -377,10 +382,7 @@ STATIC mp_obj_t re_sub_helper(mp_obj_t self_in, size_t n_args, const mp_obj_t *a
return mp_obj_new_str_from_vstr(mp_obj_get_type(where), &vstr_return);
}

STATIC mp_obj_t re_sub(size_t n_args, const mp_obj_t *args) {
return re_sub_helper(args[0], n_args, args);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_sub_obj, 3, 5, re_sub);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_sub_obj, 3, 5, re_sub_helper);

#endif

Expand Down Expand Up @@ -439,33 +441,6 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_compile_obj, 1, 2, mod_re_compile);

STATIC mp_obj_t mod_re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
(void)n_args;
mp_obj_t self = mod_re_compile(1, args);

const mp_obj_t args2[] = {self, args[1]};
mp_obj_t match = ure_exec(is_anchored, 2, args2);
return match;
}

STATIC mp_obj_t mod_re_match(size_t n_args, const mp_obj_t *args) {
return mod_re_exec(true, n_args, args);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_match_obj, 2, 4, mod_re_match);

STATIC mp_obj_t mod_re_search(size_t n_args, const mp_obj_t *args) {
return mod_re_exec(false, n_args, args);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_search_obj, 2, 4, mod_re_search);

#if MICROPY_PY_URE_SUB
STATIC mp_obj_t mod_re_sub(size_t n_args, const mp_obj_t *args) {
mp_obj_t self = mod_re_compile(1, args);
return re_sub_helper(MP_OBJ_TO_PTR(self), n_args, args);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_sub_obj, 3, 5, mod_re_sub);
#endif

#if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_rom_map_elem_t mp_module_re_globals_table[] = {
#if CIRCUITPY
Expand All @@ -474,10 +449,10 @@ STATIC const mp_rom_map_elem_t mp_module_re_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ure) },
#endif
{ MP_ROM_QSTR(MP_QSTR_compile), MP_ROM_PTR(&mod_re_compile_obj) },
{ MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&mod_re_match_obj) },
{ MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&mod_re_search_obj) },
{ MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&re_match_obj) },
{ MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&re_search_obj) },
#if MICROPY_PY_URE_SUB
{ MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&mod_re_sub_obj) },
{ MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&re_sub_obj) },
#endif
#if MICROPY_PY_URE_DEBUG
{ MP_ROM_QSTR(MP_QSTR_DEBUG), MP_ROM_INT(FLAG_DEBUG) },
Expand Down
3 changes: 0 additions & 3 deletions extmod/re1.5/compilecode.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,6 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
PC++; // Skip # of pair byte
prog->len++;
for (cnt = 0; *re != ']'; re++, cnt++) {
if (*re == '\\') {
++re;
}
if (!*re) return NULL;
const char *b = re;
if (*re == '\\') {
Expand Down
10 changes: 9 additions & 1 deletion locale/circuitpython.pot
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,10 @@ msgstr ""
msgid "Cannot specify RTS or CTS in RS485 mode"
msgstr ""

#: py/objslice.c
msgid "Cannot subclass slice"
msgstr ""

#: shared-module/bitbangio/SPI.c
msgid "Cannot transfer without MOSI and MISO pins."
msgstr ""
Expand Down Expand Up @@ -3886,10 +3890,14 @@ msgstr ""
msgid "sleep length must be non-negative"
msgstr ""

#: extmod/ulab/code/ndarray.c py/objslice.c
#: extmod/ulab/code/ndarray.c
msgid "slice step can't be zero"
msgstr ""

#: py/objslice.c
msgid "slice step cannot be zero"
msgstr ""

#: py/nativeglue.c
msgid "slice unsupported"
msgstr ""
Expand Down
4 changes: 2 additions & 2 deletions ports/unix/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ include ../../py/mkenv.mk
-include mpconfigport.mk
include $(VARIANT_DIR)/mpconfigvariant.mk

# define main target
PROG = micropython
# This should be configured by the mpconfigvariant.mk
PROG ?= micropython

# qstr definitions (must come before including py.mk)
QSTR_DEFS = qstrdefsport.h
Expand Down
3 changes: 3 additions & 0 deletions ports/unix/variants/coverage/frzmpy/frzqstr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Checks for regression on MP_QSTR_NULL
def returns_NULL():
return "NULL"
1 change: 1 addition & 0 deletions py/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -2809,6 +2809,7 @@ STATIC void compile_atom_expr_await(compiler_t *comp, mp_parse_node_struct_t *pn
EMIT_ARG(call_method, 0, 0, 0);
EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
EMIT_ARG(yield, MP_EMIT_YIELD_FROM);
reserve_labels_for_native(comp, 3);
}
#endif

Expand Down
1 change: 1 addition & 0 deletions py/objgenerator.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ STATIC mp_obj_t native_gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_k
o->base.type = &mp_type_gen_instance;

// Parse the input arguments and set up the code state
o->coroutine_generator = self->coroutine_generator;
o->pend_exc = mp_const_none;
o->code_state.fun_bc = self_fun;
o->code_state.ip = (const byte *)prelude_offset;
Expand Down
32 changes: 31 additions & 1 deletion py/objslice.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,33 @@ STATIC void slice_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
}
#endif

#if MICROPY_PY_BUILTINS_SLICE_ATTRS
STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type,
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, kw_args, 1, 3, false);

// 1st argument is the pin
mp_obj_t start = mp_const_none;
mp_obj_t stop = mp_const_none;
mp_obj_t step = mp_const_none;
if (n_args == 1) {
stop = args[0];
} else {
start = args[0];
stop = args[1];
if (n_args == 3) {
step = args[2];
}
}

return mp_obj_new_slice(start, stop, step);
}
#endif

#if MICROPY_PY_BUILTINS_SLICE_INDICES && !MICROPY_PY_BUILTINS_SLICE_ATTRS
STATIC const mp_rom_map_elem_t slice_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_indices), MP_ROM_PTR(&slice_indices_obj) },
Expand All @@ -99,6 +126,9 @@ const mp_obj_type_t mp_type_slice = {
{ &mp_type_type },
.name = MP_QSTR_slice,
.print = slice_print,
#if MICROPY_PY_BUILTINS_SLICE_INDICES
.make_new = slice_make_new,
#endif
#if MICROPY_PY_BUILTINS_SLICE_ATTRS
.attr = slice_attr,
#elif MICROPY_PY_BUILTINS_SLICE_INDICES
Expand Down Expand Up @@ -127,7 +157,7 @@ void mp_obj_slice_indices(mp_obj_t self_in, mp_int_t length, mp_bound_slice_t *r
} else {
step = mp_obj_get_int(self->step);
if (step == 0) {
mp_raise_ValueError(MP_ERROR_TEXT("slice step can't be zero"));
mp_raise_ValueError(MP_ERROR_TEXT("slice step cannot be zero"));
}
}

Expand Down
38 changes: 17 additions & 21 deletions py/runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,11 @@
#include <string.h>
#include <assert.h>


#include "extmod/vfs.h"

#include "py/parsenum.h"
#include "py/compile.h"
#include "py/mperrno.h"
#include "py/objstr.h"
#include "py/objtuple.h"
#include "py/objtype.h"
#include "py/objlist.h"
#include "py/objtype.h"
#include "py/objmodule.h"
Expand Down Expand Up @@ -1066,27 +1062,27 @@ 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);
#if MICROPY_PY_BUILTINS_PROPERTY
// If self is MP_OBJ_NULL, we looking at the class itself, not an instance.
} else if (mp_obj_is_type(member, &mp_type_property) && mp_obj_is_native_type(type) && self != MP_OBJ_NULL) {
// object member is a property; delegate the load to the property
// Note: This is an optimisation for code size and execution time.
// The proper way to do it is have the functionality just below
// in a __get__ method of the property object, and then it would
// be called by the descriptor code down below. But that way
// requires overhead for the nested mp_call's and overhead for
// the code.
const mp_obj_t *proxy = mp_obj_property_get(member);
if (proxy[0] == mp_const_none) {
mp_raise_AttributeError(translate("unreadable attribute"));
} else {
dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self);
}
#endif
} else {
// `member` is a value, so just return that value.
dest[0] = member;
}
#if MICROPY_PY_BUILTINS_PROPERTY
// If self is MP_OBJ_NULL, we looking at the class itself, not an instance.
} else if (mp_obj_is_type(member, &mp_type_property) && mp_obj_is_native_type(type) && self != MP_OBJ_NULL) {
// object member is a property; delegate the load to the property
// Note: This is an optimisation for code size and execution time.
// The proper way to do it is have the functionality just below
// in a __get__ method of the property object, and then it would
// be called by the descriptor code down below. But that way
// requires overhead for the nested mp_call's and overhead for
// the code.
const mp_obj_t *proxy = mp_obj_property_get(member);
if (proxy[0] == mp_const_none) {
mp_raise_AttributeError(translate("unreadable attribute"));
} else {
dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self);
}
#endif
} else {
// `member` is a value, so just return that value.
dest[0] = member;
Expand Down
3 changes: 3 additions & 0 deletions py/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,4 +576,7 @@ int mp_stream_posix_fsync(mp_obj_t stream) {
return res;
}

const mp_stream_p_t *mp_get_stream(mp_const_obj_t self) {
return mp_proto_get(MP_QSTR_protocol_stream, self);
}
#endif
4 changes: 1 addition & 3 deletions py/stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,7 @@ MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_ioctl_obj);
#define MP_STREAM_OP_IOCTL (4)

// Object is assumed to have a non-NULL stream protocol with valid r/w/ioctl methods
static inline const mp_stream_p_t *mp_get_stream(mp_const_obj_t self) {
return mp_proto_get(MP_QSTR_protocol_stream, self);
}
const mp_stream_p_t *mp_get_stream(mp_const_obj_t self);

const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags);
mp_obj_t mp_stream_close(mp_obj_t stream);
Expand Down
17 changes: 0 additions & 17 deletions tests/basics/memoryview1.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,6 @@
m[2] = 6
print(a)

# invalid attribute
try:
memoryview(b'a').noexist
except AttributeError:
print('AttributeError')

try:
m4[1:3] = m2[1:3]
except ValueError:
print("ValueError")

# invalid assignment on RHS
try:
memoryview(array.array('i'))[0:2] = b'1234'
except ValueError:
print('ValueError')

# invalid attribute
try:
memoryview(b'a').noexist
Expand Down
4 changes: 2 additions & 2 deletions tests/micropython/import_mpy_native_gc.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ def open(self, path, mode):
# by the required value of sys.implementation.mpy.
features0_file_contents = {
# -march=x64 -mcache-lookup-bc
0xB05: b'M\x05\x0b\x1f \x84b\xe9/\x00\x00\x00SH\x8b\x1ds\x00\x00\x00\xbe\x02\x00\x00\x00\xffS\x18\xbf\x01\x00\x00\x00H\x85\xc0u\x0cH\x8bC \xbe\x02\x00\x00\x00[\xff\xe0H\x0f\xaf\xf8H\xff\xc8\xeb\xe6ATUSH\x8b\x1dA\x00\x00\x00H\x8b\x7f\x08L\x8bc(A\xff\xd4H\x8d5\x1f\x00\x00\x00H\x89\xc5H\x8b\x05-\x00\x00\x00\x0f\xb78\xffShH\x89\xefA\xff\xd4H\x8b\x03[]A\\\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x84@\x12factorial\x10\x00\x00\r \x01"\x9f\x1c\x01\x1e\xff',
0xB05: b'M\x05\x0b\x1f \x84b\xe9/\x00\x00\x00SH\x8b\x1ds\x00\x00\x00\xbe\x02\x00\x00\x00\xffS\x18\xbf\x01\x00\x00\x00H\x85\xc0u\x0cH\x8bC \xbe\x02\x00\x00\x00[\xff\xe0H\x0f\xaf\xf8H\xff\xc8\xeb\xe6ATUSH\x8b\x1dA\x00\x00\x00H\x8b\x7f\x08H\x8bk(\xff\xd5H\x8d5 \x00\x00\x00I\x89\xc4H\x8b\x05.\x00\x00\x00\x0f\xb78\xffShL\x89\xe7\xff\xd5H\x8b\x03[]A\\\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x84@\x12factorial \x00\x00\r \x01"\x9f\x1c\x01\x1e\xff',
# -march=armv7m
0x1605: b"M\x05\x16\x1f \x84\x12\x1a\xe0\x00\x00\x13\xb5\nK\nJ{D\x9cX\x02!\xe3h\x98G\x03F\x01 3\xb9\x02!#i\x01\x93\x02\xb0\xbd\xe8\x10@\x18GXC\x01;\xf4\xe7\x00\xbfj\x00\x00\x00\x00\x00\x00\x00\xf8\xb5\tN\tK~D\xf4X@hgi\xb8G\x05F\x07K\x07I\xf2XyD\x10\x88ck\x98G(F\xb8G h\xf8\xbd6\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x01\x84\x00\x12factorial\x10\x00\x00\r<\x01>\x9f8\x01:\xff",
0x1605: b"M\x05\x16\x1f \x84\x12\x1a\xe0\x00\x00\x13\xb5\nK\nJ{D\x9cX\x02!\xe3h\x98G\x03F\x01 3\xb9\x02!#i\x01\x93\x02\xb0\xbd\xe8\x10@\x18GXC\x01;\xf4\xe7\x00\xbfj\x00\x00\x00\x00\x00\x00\x00\xf8\xb5\tN\tK~D\xf4X@hgi\xb8G\x05F\x07K\x07I\xf2XyD\x10\x88ck\x98G(F\xb8G h\xf8\xbd6\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x01\x84\x00\x12factorial \x00\x00\r<\x01>\x9f8\x01:\xff",
}

# Populate other armv7m-derived archs based on armv7m.
Expand Down
2 changes: 1 addition & 1 deletion tests/micropython/import_mpy_native_x64.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def open(self, path, mode):
b'\x12' # n bytes(=4), viper code
b'\x00\x00\x00\x00' # dummy machine code
b'\x00' # n_qstr
b'\x70' # scope_flags: VIPERBSS | VIPERRODATA | VIPERRELOC
b'\x81\x60' # scope_flags: VIPERBSS | VIPERRODATA | VIPERRELOC
b'\x00\x00' # n_obj, n_raw_code
b'\x06rodata' # rodata, 6 bytes
b'\x04' # bss, 4 bytes
Expand Down
Loading