From fab634e3eeb456e9d5dffa2cabb9ded39c45d6b6 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 3 Jul 2017 15:05:08 -0700 Subject: [PATCH] Turn on Rosie CI testing to test new builds on real hardware. This introduces a skip_if module that can be used by tests to determine when they should be skipped due to the environment. Some tests have been split in order to have finer grained skip control. --- .rosie.yml | 13 ++++ .travis.yml | 8 +++ atmel-samd/mpconfigport.h | 12 +++- index.rst | 4 ++ lib/utils/pyexec.c | 4 +- py/builtinimport.c | 2 + py/frozenmod.c | 1 - py/mkrules.mk | 1 + py/mpconfig.h | 2 +- tests/basics/array_intbig.py | 2 + tests/basics/builtin_reversed.py | 8 +-- tests/basics/bytearray_intbig.py | 11 +++ tests/basics/class_store_class.py | 3 + tests/basics/dict_fromkeys2.py | 7 +- tests/basics/dict_fromkeys_reversed.py | 7 ++ tests/basics/int_big_zeroone.py | 11 +++ tests/basics/int_bytes.py | 3 - tests/basics/int_bytes_intbig.py | 3 + tests/basics/int_longint_bytes.py | 15 ++++ tests/basics/memoryview1.py | 48 ------------- tests/basics/memoryview1_slice_assign.py | 58 ++++++++++++++++ tests/basics/namedtuple1.py | 5 -- tests/basics/namedtuple1_cpython_compat.py | 20 ++++++ tests/basics/print.py | 1 + tests/basics/self_type_check.py | 2 + tests/circuitpython/blinky.py | 2 + tests/run-tests | 32 ++++++--- tests/skip_if.py | 80 ++++++++++++++++++++++ tools/tinytest-codegen.py | 18 ++++- unix/Makefile | 4 +- unix/main.c | 3 + 31 files changed, 306 insertions(+), 84 deletions(-) create mode 100644 .rosie.yml create mode 100644 tests/basics/dict_fromkeys_reversed.py create mode 100644 tests/basics/int_longint_bytes.py create mode 100644 tests/basics/memoryview1_slice_assign.py create mode 100644 tests/basics/namedtuple1_cpython_compat.py create mode 100644 tests/circuitpython/blinky.py create mode 100644 tests/skip_if.py diff --git a/.rosie.yml b/.rosie.yml new file mode 100644 index 0000000000..d0e9fe2e26 --- /dev/null +++ b/.rosie.yml @@ -0,0 +1,13 @@ +# This configuration file tells Rosie where to find prebuilt .bin files (Travis +# builds them) and where to find the tests. + +binaries: + prebuilt_s3: adafruit-circuit-python + file_pattern: bin/{board}/adafruit-circuitpython-{board}-*-{short_sha}.{extension} + +circuitpython_tests: + test_directories: + - tests/basics + - tests/circuitpython + test_helper: + - tests/skip_if.py diff --git a/.travis.yml b/.travis.yml index 11271610b4..f137b4a00c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,14 @@ notifications: on_success: change # options: [always|never|change] default: always on_failure: always # options: [always|never|change] default: always on_start: never # options: [always|never|change] default: always + webhooks: + urls: + - https://rosie-ci.ngrok.io/travis + on_success: always + on_failure: always + on_start: always + on_cancel: always + on_error: always before_script: - sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa diff --git a/atmel-samd/mpconfigport.h b/atmel-samd/mpconfigport.h index f28f4b6577..0059ea9769 100644 --- a/atmel-samd/mpconfigport.h +++ b/atmel-samd/mpconfigport.h @@ -33,7 +33,6 @@ #define MICROPY_ENABLE_DOC_STRING (0) //#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL) -#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) #define MICROPY_PY_ASYNC_AWAIT (0) #define MICROPY_PY_BUILTINS_BYTEARRAY (1) #define MICROPY_PY_BUILTINS_MEMORYVIEW (1) @@ -61,7 +60,6 @@ #define MICROPY_PY_URANDOM_EXTRA_FUNCS (0) #define MICROPY_PY_STRUCT (1) #define MICROPY_PY_SYS (1) -#define MICROPY_CPYTHON_COMPAT (0) // If you change MICROPY_LONGINT_IMPL, also change MPY_TOOL_LONGINT_IMPL in mpconfigport.mk. #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) @@ -166,6 +164,13 @@ extern const struct _mp_obj_module_t usb_hid_module; #define MICROPY_PY_URE (1) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_FRAMEBUF (1) + + #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (1) + #define MICROPY_PY_ALL_SPECIAL_METHODS (1) + #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) + #define MICROPY_PY_SYS_MAXSIZE (1) + #define MICROPY_CPYTHON_COMPAT (1) + #define EXTRA_BUILTIN_MODULES \ { MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_audiobusio), (mp_obj_t)&audiobusio_module }, \ @@ -177,6 +182,9 @@ extern const struct _mp_obj_module_t usb_hid_module; #define MICROPY_PY_MICROPYTHON_MEM_INFO (0) #define MICROPY_PY_FRAMEBUF (0) #define EXTRA_BUILTIN_MODULES + + #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) + #define MICROPY_CPYTHON_COMPAT (0) #endif #define MICROPY_PORT_BUILTIN_MODULES \ diff --git a/index.rst b/index.rst index 49b73ee896..8f83c02085 100644 --- a/index.rst +++ b/index.rst @@ -13,6 +13,10 @@ Adafruit CircuitPython API Reference :target: https://gitter.im/adafruit/circuitpython?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge :alt: Gitter +.. image :: https://img.shields.io/discord/327254708534116352.svg + :target: https://adafru.it/discord + :alt: Discord + Welcome! This is the documentation for Adafruit CircuitPython. It is an open source derivative of `MicroPython `_ for use on educational development boards designed and sold by `Adafruit diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c index 31a97deafd..fc04e3f9f3 100644 --- a/lib/utils/pyexec.c +++ b/lib/utils/pyexec.c @@ -136,7 +136,9 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input if (mp_obj_is_exception_instance(return_value)) { size_t n, *values; mp_obj_exception_get_traceback(return_value, &n, &values); - result->exception_line = values[n - 2]; + if (values != NULL) { + result->exception_line = values[n - 2]; + } } } } diff --git a/py/builtinimport.c b/py/builtinimport.c index 01dddd02ba..fc73567cde 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -115,6 +115,7 @@ STATIC mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *d vstr_reset(dest); size_t p_len; const char *p = mp_obj_str_get_data(path_items[i], &p_len); + DEBUG_printf("Looking in path: %d =%s=\n", i, p); if (p_len > 0) { vstr_add_strn(dest, p, p_len); vstr_add_char(dest, PATH_SEP_CHAR); @@ -386,6 +387,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { mp_import_stat_t stat; if (vstr_len(&path) == 0) { // first module in the dotted-name; search for a directory or file + DEBUG_printf("Find file =%.*s=\n", vstr_len(&path), vstr_str(&path)); stat = find_file(mod_str, i, &path); } else { // latter module in the dotted-name; append to path diff --git a/py/frozenmod.c b/py/frozenmod.c index 782b437af5..5a099ac969 100644 --- a/py/frozenmod.c +++ b/py/frozenmod.c @@ -72,7 +72,6 @@ STATIC mp_lexer_t *mp_lexer_frozen_str(const char *str, size_t str_len) { mp_lexer_t *lex = MICROPY_MODULE_FROZEN_LEXER(source, content, file_len, 0); return lex; } - #endif #if MICROPY_MODULE_FROZEN_MPY diff --git a/py/mkrules.mk b/py/mkrules.mk index 6b9f642f0f..d61e1dda06 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -107,6 +107,7 @@ $(TOP)/mpy-cross/mpy-cross: $(TOP)/py/*.[ch] $(TOP)/mpy-cross/*.[ch] $(TOP)/wind $(Q)$(MAKE) -C $(TOP)/mpy-cross # make a list of all the .py files that need compiling and freezing +BLAH := $(info $(shell pwd)) FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py' | $(SED) -e 's=^$(FROZEN_MPY_DIR)/==') FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/frozen_mpy/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) diff --git a/py/mpconfig.h b/py/mpconfig.h index 14c5af3e76..6cbadb6234 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -40,7 +40,7 @@ // to another, you must rebuild from scratch using "-B" switch to make. #ifdef MP_CONFIGFILE -#include MP_CONFIGFILE +#include "mpconfigport_coverage.h" #else #include #endif diff --git a/tests/basics/array_intbig.py b/tests/basics/array_intbig.py index 5702a8ae63..ef3b567935 100644 --- a/tests/basics/array_intbig.py +++ b/tests/basics/array_intbig.py @@ -1,4 +1,6 @@ # test array types QqLl that require big-ints +import skip_if +skip_if.no_bigint() try: from array import array diff --git a/tests/basics/builtin_reversed.py b/tests/basics/builtin_reversed.py index f43505a8bf..6f07beaadd 100644 --- a/tests/basics/builtin_reversed.py +++ b/tests/basics/builtin_reversed.py @@ -1,9 +1,5 @@ -# test the builtin reverse() function -try: - reversed -except: - print("SKIP") - raise SystemExit +import skip_if +skip_if.no_reversed() # list print(list(reversed([]))) diff --git a/tests/basics/bytearray_intbig.py b/tests/basics/bytearray_intbig.py index 334eabe122..77bcf22254 100644 --- a/tests/basics/bytearray_intbig.py +++ b/tests/basics/bytearray_intbig.py @@ -1 +1,12 @@ +# Skip if long ints are not supported. +try: + # We have to use variables because 1 << 40 causes an exception on parse and + # cannot be caught. + x = 40 + x = 1 << x +except OverflowError: + print("SKIP") + import sys + sys.exit(1) + print(bytearray(2**65 - (2**65 - 1))) diff --git a/tests/basics/class_store_class.py b/tests/basics/class_store_class.py index 797f88f852..8f3e542d11 100644 --- a/tests/basics/class_store_class.py +++ b/tests/basics/class_store_class.py @@ -11,6 +11,9 @@ except ImportError: print("SKIP") raise SystemExit +import skip_if +skip_if.no_cpython_compat() + _DefragResultBase = namedtuple('DefragResult', [ 'foo', 'bar' ]) class _ResultMixinStr(object): diff --git a/tests/basics/dict_fromkeys2.py b/tests/basics/dict_fromkeys2.py index dce1e8ef5a..a5371bc538 100644 --- a/tests/basics/dict_fromkeys2.py +++ b/tests/basics/dict_fromkeys2.py @@ -1,8 +1,5 @@ -try: - reversed -except: - print("SKIP") - raise SystemExit +import skip_if +skip_if.no_reversed() # argument to fromkeys has no __len__ d = dict.fromkeys(reversed(range(1))) diff --git a/tests/basics/dict_fromkeys_reversed.py b/tests/basics/dict_fromkeys_reversed.py new file mode 100644 index 0000000000..34b0ed129c --- /dev/null +++ b/tests/basics/dict_fromkeys_reversed.py @@ -0,0 +1,7 @@ +# Skip this test if reversed() isn't built in. +import skip_if +skip_if.no_reversed() + +# argument to fromkeys has no __len__ +d = dict.fromkeys(reversed(range(1))) +print(d) diff --git a/tests/basics/int_big_zeroone.py b/tests/basics/int_big_zeroone.py index 7e0b7a720e..131d96c76b 100644 --- a/tests/basics/int_big_zeroone.py +++ b/tests/basics/int_big_zeroone.py @@ -1,5 +1,16 @@ # test [0,-0,1,-1] edge cases of bignum +# Skip if long ints are not supported. +try: + # We have to use variables because 1 << 40 causes an exception on parse and + # cannot be caught. + x = 40 + x = 1 << x +except OverflowError: + print("SKIP") + import sys + sys.exit(1) + long_zero = (2**64) >> 65 long_neg_zero = -long_zero long_one = long_zero + 1 diff --git a/tests/basics/int_bytes.py b/tests/basics/int_bytes.py index 93c00bba10..a96a4e65ff 100644 --- a/tests/basics/int_bytes.py +++ b/tests/basics/int_bytes.py @@ -1,9 +1,6 @@ print((10).to_bytes(1, "little")) print((111111).to_bytes(4, "little")) print((100).to_bytes(10, "little")) -print(int.from_bytes(b"\x00\x01\0\0\0\0\0\0", "little")) -print(int.from_bytes(b"\x01\0\0\0\0\0\0\0", "little")) -print(int.from_bytes(b"\x00\x01\0\0\0\0\0\0", "little")) # check that extra zero bytes don't change the internal int value print(int.from_bytes(bytes(20), "little") == 0) diff --git a/tests/basics/int_bytes_intbig.py b/tests/basics/int_bytes_intbig.py index 0e0ad1cbb7..7c8a7f4afe 100644 --- a/tests/basics/int_bytes_intbig.py +++ b/tests/basics/int_bytes_intbig.py @@ -1,3 +1,6 @@ +import skip_if +skip_if.no_bigint() + print((2**64).to_bytes(9, "little")) b = bytes(range(20)) diff --git a/tests/basics/int_longint_bytes.py b/tests/basics/int_longint_bytes.py new file mode 100644 index 0000000000..31510d75ad --- /dev/null +++ b/tests/basics/int_longint_bytes.py @@ -0,0 +1,15 @@ +# Skip if long ints are not supported. +try: + # We have to use variables because 1 << 40 causes an exception on parse and + # cannot be caught. + x = 40 + x = 1 << x +except OverflowError: + print("SKIP") + import sys + sys.exit(1) + +print((2**64).to_bytes(9, "little")) +print(int.from_bytes(b"\x00\x01\0\0\0\0\0\0", "little")) +print(int.from_bytes(b"\x01\0\0\0\0\0\0\0", "little")) +print(int.from_bytes(b"\x00\x01\0\0\0\0\0\0", "little")) diff --git a/tests/basics/memoryview1.py b/tests/basics/memoryview1.py index c4cc6ffab7..3e5c86768c 100644 --- a/tests/basics/memoryview1.py +++ b/tests/basics/memoryview1.py @@ -46,51 +46,3 @@ print(list(m)) print(list(m[1:-1])) m[2] = 6 print(a) - -# test slice assignment between memoryviews -b1 = bytearray(b'1234') -b2 = bytearray(b'5678') -b3 = bytearray(b'5678') -m1 = memoryview(b1) -m2 = memoryview(b2) -m3 = memoryview(b3) -m2[1:3] = m1[0:2] -print(b2) -b3[1:3] = m1[0:2] -print(b3) -m1[2:4] = b3[1:3] -print(b1) - -try: - m2[1:3] = b1[0:4] -except ValueError: - print("ValueError") - -try: - m2[1:3] = m1[0:4] -except ValueError: - print("ValueError") - -try: - m2[0:4] = m1[1:3] -except ValueError: - print("ValueError") - -# test memoryview of arrays with items sized larger than 1 -a1 = array.array('i', [0]*5) -m4 = memoryview(a1) -a2 = array.array('i', [3]*5) -m5 = memoryview(a2) -m4[1:3] = m5[1:3] -print(a1) - -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') diff --git a/tests/basics/memoryview1_slice_assign.py b/tests/basics/memoryview1_slice_assign.py new file mode 100644 index 0000000000..f272fd392f --- /dev/null +++ b/tests/basics/memoryview1_slice_assign.py @@ -0,0 +1,58 @@ +import skip_if + +try: + memoryview +except: + skip_if.skip() + +skip_if.no_slice_assign() + +# test slice assignment between memoryviews +b1 = bytearray(b'1234') +b2 = bytearray(b'5678') +b3 = bytearray(b'5678') +m1 = memoryview(b1) +m2 = memoryview(b2) +m3 = memoryview(b3) +m2[1:3] = m1[0:2] +print(b2) +b3[1:3] = m1[0:2] +print(b3) +m1[2:4] = b3[1:3] +print(b1) + +try: + m2[1:3] = b1[0:4] +except ValueError: + print("ValueError") + +try: + m2[1:3] = m1[0:4] +except ValueError: + print("ValueError") + +try: + m2[0:4] = m1[1:3] +except ValueError: + print("ValueError") + +import array + +# test memoryview of arrays with items sized larger than 1 +a1 = array.array('i', [0]*5) +m4 = memoryview(a1) +a2 = array.array('i', [3]*5) +m5 = memoryview(a2) +m4[1:3] = m5[1:3] +print(a1) + +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') diff --git a/tests/basics/namedtuple1.py b/tests/basics/namedtuple1.py index b9a007240c..56c29ddda4 100644 --- a/tests/basics/namedtuple1.py +++ b/tests/basics/namedtuple1.py @@ -65,11 +65,6 @@ try: except TypeError: print("TypeError") -# Try single string -T3 = namedtuple("TupComma", "foo bar") -t = T3(1, 2) -print(t.foo, t.bar) - # Try tuple T4 = namedtuple("TupTuple", ("foo", "bar")) t = T4(1, 2) diff --git a/tests/basics/namedtuple1_cpython_compat.py b/tests/basics/namedtuple1_cpython_compat.py new file mode 100644 index 0000000000..a1b852d900 --- /dev/null +++ b/tests/basics/namedtuple1_cpython_compat.py @@ -0,0 +1,20 @@ +import skip_if +skip_if.no_cpython_compat() + +try: + try: + from collections import namedtuple + except ImportError: + from ucollections import namedtuple +except ImportError: + skip_if.skip() + +# Try single string +T3 = namedtuple("TupComma", "foo bar") +t = T3(1, 2) +print(t.foo, t.bar) + +# Try single string with comma field separator +# Not implemented so far +#T2 = namedtuple("TupComma", "foo,bar") +#t = T2(1, 2) diff --git a/tests/basics/print.py b/tests/basics/print.py index 880aaf44f9..8b53e32c95 100644 --- a/tests/basics/print.py +++ b/tests/basics/print.py @@ -1,5 +1,6 @@ # test builtin print function +print("break the test") print() print(None) print('') diff --git a/tests/basics/self_type_check.py b/tests/basics/self_type_check.py index 947e362cdb..206678e25d 100644 --- a/tests/basics/self_type_check.py +++ b/tests/basics/self_type_check.py @@ -1,4 +1,6 @@ # make sure type of first arg (self) to a builtin method is checked +import skip_if +skip_if.board_in("gemma_m0", "trinket_m0") list.append diff --git a/tests/circuitpython/blinky.py b/tests/circuitpython/blinky.py new file mode 100644 index 0000000000..a9412b07c6 --- /dev/null +++ b/tests/circuitpython/blinky.py @@ -0,0 +1,2 @@ +import digitalio +import board diff --git a/tests/run-tests b/tests/run-tests index f24fc09617..a45477dea6 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -123,9 +123,13 @@ def run_micropython(pyb, args, test_file, is_special=False): cmdlist.append(test_file) # run the actual test - try: - output_mupy = subprocess.check_output(cmdlist) - except subprocess.CalledProcessError: + e = {"MICROPYPATH": os.getcwd() + ":", "LANG": "en_US.UTF-8"} + p = subprocess.Popen(cmdlist, env=e, stdout=subprocess.PIPE) + output_mupy = b'' + while p.poll() is None: + output_mupy += p.stdout.read() + output_mupy += p.stdout.read() + if p.returncode != 0: output_mupy = b'CRASH' # clean up if we had an intermediate .mpy file @@ -368,13 +372,19 @@ def run_tests(pyb, tests, args, base_path="."): output_expected = f.read() else: # run CPython to work out expected output - try: - output_expected = subprocess.check_output([CPYTHON3, '-B', test_file]) - if args.write_exp: - with open(test_file_expected, 'wb') as f: - f.write(output_expected) - except subprocess.CalledProcessError: + e = {"PYTHONPATH": os.getcwd(), + "PATH": os.environ["PATH"], + "LANG": "en_US.UTF-8"} + p = subprocess.Popen([CPYTHON3, '-B', test_file], env=e, stdout=subprocess.PIPE) + output_expected = b'' + while p.poll() is None: + output_expected += p.stdout.read() + output_expected += p.stdout.read() + if p.returncode != 0: output_expected = b'CPYTHON3 CRASH' + elif args.write_exp: + with open(test_file_expected, 'wb') as f: + f.write(output_expected) # canonical form for all host platforms is to use \n for end-of-line output_expected = output_expected.replace(b'\r\n', b'\n') @@ -405,6 +415,10 @@ def run_tests(pyb, tests, args, base_path="."): f.write(output_expected) with open(filename_mupy, "wb") as f: f.write(output_mupy) + print("### Expected") + print(output_expected) + print("### Actual") + print(output_mupy) print("FAIL ", test_file) failed_tests.append(test_name) diff --git a/tests/skip_if.py b/tests/skip_if.py new file mode 100644 index 0000000000..f6d22b4c1f --- /dev/null +++ b/tests/skip_if.py @@ -0,0 +1,80 @@ +# The MIT License (MIT) +# +# Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# This must be on one line so its skipped when built into tests. +"""This file provides helpers to detect particular running conditions and skip the test when appropriate.""" + +def skip(): + print("SKIP") + raise SystemExit + +def no_reversed(): + import builtins + if "reversed" not in dir(builtins): + skip() + +def no_bigint(): + try: + # We have to use variables because 1 << 40 causes an exception on parse and + # cannot be caught. + x = 40 + x = 1 << x + except OverflowError: + skip() + +def board_in(*board): + try: + import test_env + except ImportError: + class Env: + def __init__(self, board): + self.board = board + test_env = Env("unknown") + if test_env.board in board: + skip() + +def no_cpython_compat(): + try: + try: + from collections import namedtuple + except ImportError: + from ucollections import namedtuple + except ImportError: + skip() + try: + T3 = namedtuple("TupComma", "foo bar") + except TypeError: + skip() + +def no_slice_assign(): + try: + memoryview + except: + skip() + b1 = bytearray(b'1234') + b2 = bytearray(b'5678') + m1 = memoryview(b1) + m2 = memoryview(b2) + try: + m2[1:3] = m1[0:2] + except TypeError: + skip() diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py index dadfea1ccc..0f9e628476 100755 --- a/tools/tinytest-codegen.py +++ b/tools/tinytest-codegen.py @@ -20,7 +20,23 @@ def chew_filename(t): def script_to_map(t): r = { 'name': chew_filename(t)['func'] } - with open(t) as f: r['script'] = escape(''.join(f.readlines())) + with open(t) as test: + script = test.readlines() + + # Test for import skip_if and inject it into the test as needed. + if "import skip_if\n" in script: + index = script.index("import skip_if\n") + script.pop(index) + script.insert(index, "class skip_if:\n") + with open("../tests/skip_if.py") as skip_if: + total_lines = 1 + for line in skip_if: + stripped = line.strip() + if not stripped or stripped.startswith(("#", "\"\"\"")): + continue + script.insert(index + total_lines, "\t" + line) + total_lines += 1 + r['script'] = escape(''.join(script)) return r test_function = ( diff --git a/unix/Makefile b/unix/Makefile index be324dd3dd..d632a949ce 100644 --- a/unix/Makefile +++ b/unix/Makefile @@ -242,8 +242,8 @@ freedos: # build an interpreter for coverage testing and do the testing coverage: - $(MAKE) \ - COPT="-O0" CFLAGS_EXTRA='-DMP_CONFIGFILE="" \ + $(MAKE) V=2 \ + COPT="-O0" CFLAGS_EXTRA='-DMP_CONFIGFILE="\"mpconfigport_coverage.h\"" \ -fprofile-arcs -ftest-coverage \ -Wdouble-promotion -Wformat -Wmissing-declarations -Wmissing-prototypes -Wsign-compare \ -Wold-style-definition -Wpointer-arith -Wshadow -Wuninitialized -Wunused-parameter \ diff --git a/unix/main.c b/unix/main.c index e96cdaaa25..8c7ddf5974 100644 --- a/unix/main.c +++ b/unix/main.c @@ -492,6 +492,9 @@ MP_NOINLINE int main_(int argc, char **argv) { } } + + + mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); #if defined(MICROPY_UNIX_COVERAGE)