summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/basics/array_intbig.py (renamed from tests/basics/array_q.py)5
-rw-r--r--tests/basics/array_micropython.py7
-rw-r--r--tests/basics/attrtuple1.py9
-rw-r--r--tests/basics/boundmeth1.py6
-rw-r--r--tests/basics/builtin_abs.py8
-rw-r--r--tests/basics/builtin_abs_intbig.py9
-rw-r--r--tests/basics/builtin_bin.py1
-rw-r--r--tests/basics/builtin_bin_intbig.py3
-rw-r--r--tests/basics/builtin_delattr.py6
-rw-r--r--tests/basics/builtin_dir.py2
-rw-r--r--tests/basics/builtin_divmod.py12
-rw-r--r--tests/basics/builtin_divmod_intbig.py13
-rw-r--r--tests/basics/builtin_hash.py8
-rw-r--r--tests/basics/builtin_hash_intbig.py10
-rw-r--r--tests/basics/builtin_help.py18
-rw-r--r--tests/basics/builtin_help.py.exp14
-rw-r--r--tests/basics/builtin_hex.py3
-rw-r--r--tests/basics/builtin_hex_intbig.py4
-rw-r--r--tests/basics/builtin_minmax.py7
-rw-r--r--tests/basics/builtin_oct.py3
-rw-r--r--tests/basics/builtin_oct_intbig.py4
-rw-r--r--tests/basics/builtin_override.py8
-rw-r--r--tests/basics/builtin_pow.py6
-rw-r--r--tests/basics/builtin_pow3.py25
-rw-r--r--tests/basics/builtin_pow3_intbig.py23
-rw-r--r--tests/basics/builtin_property.py6
-rw-r--r--tests/basics/builtin_range.py19
-rw-r--r--tests/basics/builtin_range_attrs.py19
-rw-r--r--tests/basics/builtin_reversed.py6
-rw-r--r--tests/basics/builtin_sorted.py7
-rw-r--r--tests/basics/bytearray_construct.py6
-rw-r--r--tests/basics/bytearray_construct_array.py11
-rw-r--r--tests/basics/bytearray_construct_endian.py8
-rw-r--r--tests/basics/bytearray_intbig.py (renamed from tests/basics/bytearray_longint.py)0
-rw-r--r--tests/basics/bytearray_slice_assign.py5
-rw-r--r--tests/basics/bytes_add.py9
-rw-r--r--tests/basics/bytes_add_array.py12
-rw-r--r--tests/basics/bytes_add_endian.py8
-rw-r--r--tests/basics/bytes_compare2.py6
-rw-r--r--tests/basics/bytes_compare_array.py10
-rw-r--r--tests/basics/bytes_construct.py9
-rw-r--r--tests/basics/bytes_construct_array.py11
-rw-r--r--tests/basics/bytes_construct_endian.py7
-rw-r--r--tests/basics/bytes_construct_intbig.py4
-rw-r--r--tests/basics/class_delattr_setattr.py63
-rw-r--r--tests/basics/class_descriptor.py7
-rw-r--r--tests/basics/class_new.py8
-rw-r--r--tests/basics/class_store_class.py7
-rw-r--r--tests/basics/class_super.py14
-rw-r--r--tests/basics/class_super_aslocal.py9
-rw-r--r--tests/basics/class_super_closure.py18
-rw-r--r--tests/basics/class_super_object.py8
-rw-r--r--tests/basics/comprehension1.py3
-rw-r--r--tests/basics/containment.py3
-rw-r--r--tests/basics/dict_fromkeys.py4
-rw-r--r--tests/basics/dict_fromkeys2.py11
-rw-r--r--tests/basics/enumerate.py7
-rw-r--r--tests/basics/filter.py7
-rw-r--r--tests/basics/floordivide.py15
-rw-r--r--tests/basics/floordivide_intbig.py15
-rw-r--r--tests/basics/for_range.py7
-rw-r--r--tests/basics/fun_calldblstar3.py3
-rw-r--r--tests/basics/fun_callstar.py5
-rw-r--r--tests/basics/fun_error.py3
-rw-r--r--tests/basics/fun_error2.py19
-rw-r--r--tests/basics/gen_yield_from_close.py2
-rw-r--r--tests/basics/gen_yield_from_throw2.py15
-rw-r--r--tests/basics/gen_yield_from_throw2.py.exp3
-rw-r--r--tests/basics/gen_yield_from_throw3.py30
-rw-r--r--tests/basics/int_big1.py (renamed from tests/basics/int_mpz.py)0
-rw-r--r--tests/basics/int_bytes.py5
-rw-r--r--tests/basics/int_bytes_intbig.py12
-rw-r--r--tests/basics/int_bytes_notimpl.py5
-rw-r--r--tests/basics/int_bytes_notimpl.py.exp1
-rw-r--r--tests/basics/int_constfolding.py14
-rw-r--r--tests/basics/int_constfolding_intbig.py19
-rw-r--r--tests/basics/int_divmod.py8
-rw-r--r--tests/basics/int_divmod_intbig.py9
-rw-r--r--tests/basics/int_intbig.py (renamed from tests/basics/int_long.py)0
-rw-r--r--tests/basics/iter0.py3
-rw-r--r--tests/basics/iter_of_iter.py3
-rw-r--r--tests/basics/lexer.py16
-rw-r--r--tests/basics/list_slice_3arg.py11
-rw-r--r--tests/basics/list_slice_assign.py11
-rw-r--r--tests/basics/list_slice_assign_grow.py5
-rw-r--r--tests/basics/map.py2
-rw-r--r--tests/basics/memoryview1.py10
-rw-r--r--tests/basics/memoryview2.py13
-rw-r--r--tests/basics/memoryview_gc.py6
-rw-r--r--tests/basics/memoryview_intbig.py11
-rw-r--r--tests/basics/namedtuple1.py9
-rw-r--r--tests/basics/object_new.py8
-rw-r--r--tests/basics/op_error.py2
-rw-r--r--tests/basics/op_error_intbig.py13
-rw-r--r--tests/basics/op_error_memoryview.py19
-rw-r--r--tests/basics/ordereddict1.py11
-rw-r--r--tests/basics/python34.py9
-rw-r--r--tests/basics/python34.py.exp2
-rw-r--r--tests/basics/set_binop.py19
-rw-r--r--tests/basics/set_comprehension.py1
-rw-r--r--tests/basics/set_containment.py4
-rw-r--r--tests/basics/set_iter_of_iter.py2
-rw-r--r--tests/basics/slice_intbig.py (renamed from tests/basics/slice_bignum.py)0
-rw-r--r--tests/basics/special_methods.py40
-rw-r--r--tests/basics/special_methods2.py145
-rw-r--r--tests/basics/string_format2.py2
-rw-r--r--tests/basics/string_format_modulo.py48
-rw-r--r--tests/basics/string_format_modulo_int.py41
-rw-r--r--tests/basics/string_join.py15
-rw-r--r--tests/basics/struct1.py28
-rw-r--r--tests/basics/struct1_intbig.py37
-rw-r--r--tests/basics/struct2.py12
-rw-r--r--tests/basics/struct_micropython.py13
-rw-r--r--tests/basics/subclass_classmethod.py7
-rw-r--r--tests/basics/syntaxerror.py4
-rw-r--r--tests/basics/sys1.py14
-rw-r--r--tests/basics/try_finally_loops.py25
-rw-r--r--tests/basics/tuple1.py4
-rw-r--r--tests/basics/unpack1.py2
-rw-r--r--tests/basics/zip.py10
-rw-r--r--tests/cmdline/cmd_parsetree.py.exp32
-rw-r--r--tests/cmdline/cmd_showbc.py4
-rw-r--r--tests/cmdline/cmd_showbc.py.exp92
-rw-r--r--tests/cpydiff/core_arguments.py10
-rw-r--r--tests/cpydiff/core_class_delnotimpl.py16
-rw-r--r--tests/cpydiff/core_class_supermultiple.py27
-rw-r--r--tests/cpydiff/core_class_superproperty.py18
-rw-r--r--tests/cpydiff/core_function_unpacking.py7
-rw-r--r--tests/cpydiff/core_function_userattr.py11
-rw-r--r--tests/cpydiff/core_generator_noexit.py24
-rw-r--r--tests/cpydiff/core_import_path.py9
-rw-r--r--tests/cpydiff/core_import_prereg.py17
-rw-r--r--tests/cpydiff/core_import_split_ns_pkgs.py14
-rw-r--r--tests/cpydiff/core_mro.py15
-rw-r--r--tests/cpydiff/modules/__init__.py0
-rw-r--r--tests/cpydiff/modules/foo.py2
-rw-r--r--tests/cpydiff/modules/subpkg/foo.py0
-rw-r--r--tests/cpydiff/modules2/subpkg/bar.py0
-rw-r--r--tests/cpydiff/modules_array_containment.py8
-rw-r--r--tests/cpydiff/modules_array_deletion.py10
-rw-r--r--tests/cpydiff/modules_array_subscrstep.py9
-rw-r--r--tests/cpydiff/modules_deque.py9
-rw-r--r--tests/cpydiff/modules_json_nonserializable.py14
-rw-r--r--tests/cpydiff/modules_struct_fewargs.py12
-rw-r--r--tests/cpydiff/modules_struct_manyargs.py12
-rw-r--r--tests/cpydiff/modules_sys_stdassign.py9
-rw-r--r--tests/cpydiff/syntax_spaces.py18
-rw-r--r--tests/cpydiff/syntax_unicode_nameesc.py7
-rw-r--r--tests/cpydiff/types_bytearray_sliceassign.py9
-rw-r--r--tests/cpydiff/types_bytes_keywords.py7
-rw-r--r--tests/cpydiff/types_bytes_subscrstep.py7
-rw-r--r--tests/cpydiff/types_exception_chaining.py10
-rw-r--r--tests/cpydiff/types_exception_instancevar.py9
-rw-r--r--tests/cpydiff/types_exception_loops.py12
-rw-r--r--tests/cpydiff/types_exception_subclassinit.py11
-rw-r--r--tests/cpydiff/types_float_rounding.py9
-rw-r--r--tests/cpydiff/types_int_subclassconv.py11
-rw-r--r--tests/cpydiff/types_int_tobytesfloat.py10
-rw-r--r--tests/cpydiff/types_list_delete_subscrstep.py9
-rw-r--r--tests/cpydiff/types_list_store_noniter.py9
-rw-r--r--tests/cpydiff/types_list_store_subscrstep.py9
-rw-r--r--tests/cpydiff/types_str_decodeerror.py11
-rw-r--r--tests/cpydiff/types_str_endswith.py7
-rw-r--r--tests/cpydiff/types_str_formatsubscr.py7
-rw-r--r--tests/cpydiff/types_str_keywords.py7
-rw-r--r--tests/cpydiff/types_str_rsplitnone.py7
-rw-r--r--tests/cpydiff/types_str_subclassequality.py11
-rw-r--r--tests/cpydiff/types_str_subscrstep.py7
-rw-r--r--tests/cpydiff/types_tuple_subscrstep.py7
-rw-r--r--tests/extmod/framebuf1.py179
-rw-r--r--tests/extmod/framebuf1.py.exp47
-rw-r--r--tests/extmod/framebuf4.py54
-rw-r--r--tests/extmod/framebuf4.py.exp112
-rw-r--r--tests/extmod/machine1.py3
-rw-r--r--tests/extmod/machine_pulse.py11
-rw-r--r--tests/extmod/machine_pulse.py.exp4
-rw-r--r--tests/extmod/machine_signal.py40
-rw-r--r--tests/extmod/machine_signal.py.exp4
-rw-r--r--tests/extmod/ubinascii_a2b_base64.py9
-rw-r--r--tests/extmod/ubinascii_b2a_base64.py9
-rw-r--r--tests/extmod/ubinascii_crc32.py10
-rw-r--r--tests/extmod/ubinascii_hexlify.py9
-rw-r--r--tests/extmod/ubinascii_micropython.py9
-rw-r--r--tests/extmod/ubinascii_unhexlify.py9
-rw-r--r--tests/extmod/uctypes_32bit_intbig.py54
-rw-r--r--tests/extmod/uctypes_32bit_intbig.py.exp11
-rw-r--r--tests/extmod/uctypes_array_assign_le.py7
-rw-r--r--tests/extmod/uctypes_array_assign_native_le.py16
-rw-r--r--tests/extmod/uctypes_array_assign_native_le.py.exp2
-rw-r--r--tests/extmod/uctypes_array_assign_native_le_intbig.py43
-rw-r--r--tests/extmod/uctypes_array_assign_native_le_intbig.py.exp2
-rw-r--r--tests/extmod/uctypes_bytearray.py7
-rw-r--r--tests/extmod/uctypes_le.py7
-rw-r--r--tests/extmod/uctypes_le_float.py7
-rw-r--r--tests/extmod/uctypes_native_float.py7
-rw-r--r--tests/extmod/uctypes_native_le.py6
-rw-r--r--tests/extmod/uctypes_print.py8
-rw-r--r--tests/extmod/uctypes_ptr_le.py6
-rw-r--r--tests/extmod/uctypes_ptr_native_le.py6
-rw-r--r--tests/extmod/uctypes_sizeof.py7
-rw-r--r--tests/extmod/uctypes_sizeof_native.py7
-rw-r--r--tests/extmod/uheapq1.py7
-rw-r--r--tests/extmod/ujson_dumps.py7
-rw-r--r--tests/extmod/ujson_dumps_extra.py7
-rw-r--r--tests/extmod/ujson_dumps_float.py7
-rw-r--r--tests/extmod/ujson_load.py9
-rw-r--r--tests/extmod/ujson_loads.py9
-rw-r--r--tests/extmod/ujson_loads_float.py9
-rw-r--r--tests/extmod/urandom_basic.py7
-rw-r--r--tests/extmod/urandom_extra.py7
-rw-r--r--tests/extmod/ure1.py16
-rw-r--r--tests/extmod/ure_debug.py9
-rw-r--r--tests/extmod/ure_debug.py.exp15
-rw-r--r--tests/extmod/ure_error.py9
-rw-r--r--tests/extmod/ure_group.py9
-rw-r--r--tests/extmod/ure_namedclass.py9
-rw-r--r--tests/extmod/ure_split.py7
-rw-r--r--tests/extmod/ure_split_empty.py7
-rw-r--r--tests/extmod/ure_split_notimpl.py12
-rw-r--r--tests/extmod/ure_split_notimpl.py.exp1
-rw-r--r--tests/extmod/ussl_basic.py52
-rw-r--r--tests/extmod/ussl_basic.py.exp8
-rw-r--r--tests/extmod/utimeq1.py35
-rw-r--r--tests/extmod/uzlib_decompio.py8
-rw-r--r--tests/extmod/uzlib_decompio_gz.py18
-rw-r--r--tests/extmod/uzlib_decompio_gz.py.exp2
-rw-r--r--tests/extmod/uzlib_decompress.py7
-rw-r--r--tests/extmod/vfs_basic.py147
-rw-r--r--tests/extmod/vfs_basic.py.exp56
-rw-r--r--tests/extmod/vfs_fat_fileio.py.exp25
-rw-r--r--tests/extmod/vfs_fat_fileio1.py118
-rw-r--r--tests/extmod/vfs_fat_fileio1.py.exp13
-rw-r--r--tests/extmod/vfs_fat_fileio2.py (renamed from tests/extmod/vfs_fat_fileio.py)106
-rw-r--r--tests/extmod/vfs_fat_fileio2.py.exp11
-rw-r--r--tests/extmod/vfs_fat_fsusermount.py96
-rw-r--r--tests/extmod/vfs_fat_fsusermount.py.exp7
-rw-r--r--tests/extmod/vfs_fat_more.py117
-rw-r--r--tests/extmod/vfs_fat_more.py.exp28
-rw-r--r--tests/extmod/vfs_fat_oldproto.py33
-rw-r--r--tests/extmod/vfs_fat_oldproto.py.exp3
-rw-r--r--tests/extmod/vfs_fat_ramdisk.py46
-rw-r--r--tests/extmod/vfs_fat_ramdisk.py.exp19
-rw-r--r--tests/extmod/websocket_basic.py61
-rw-r--r--tests/extmod/websocket_basic.py.exp14
-rw-r--r--tests/feature_check/async_check.py3
-rw-r--r--tests/feature_check/async_check.py.exp0
-rw-r--r--tests/feature_check/const.py1
-rw-r--r--tests/feature_check/const.py.exp0
-rw-r--r--tests/feature_check/int_big.py2
-rw-r--r--tests/feature_check/int_big.py.exp1
-rw-r--r--tests/float/array_construct.py7
-rw-r--r--tests/float/builtin_float_hash.py22
-rw-r--r--tests/float/builtin_float_minmax.py7
-rw-r--r--tests/float/builtin_float_round.py7
-rw-r--r--tests/float/builtin_float_round_intbig.py4
-rw-r--r--tests/float/bytearray_construct.py7
-rw-r--r--tests/float/bytes_construct.py7
-rw-r--r--tests/float/complex1.py16
-rw-r--r--tests/float/complex1_intbig.py4
-rw-r--r--tests/float/float1.py5
-rw-r--r--tests/float/float2int_doubleprec_intbig.py (renamed from tests/float/float2int_doubleprec.py)32
-rw-r--r--tests/float/float2int_fp30_intbig.py (renamed from tests/float/float2int_fp30.py)32
-rw-r--r--tests/float/float2int_intbig.py (renamed from tests/float/float2int.py)34
-rw-r--r--tests/float/float_array.py7
-rw-r--r--tests/float/float_struct.py12
-rw-r--r--tests/float/int_divzero.py5
-rw-r--r--tests/float/math_fun_int.py15
-rw-r--r--tests/float/math_fun_intbig.py12
-rw-r--r--tests/float/string_format_modulo2.py4
-rw-r--r--tests/float/string_format_modulo2_intbig.py21
-rw-r--r--tests/import/import_pkg7.py2
-rw-r--r--tests/import/import_pkg8.py2
-rw-r--r--tests/import/pkg7/subpkg1/subpkg2/mod3.py7
-rw-r--r--tests/import/pkg8/mod.py1
-rw-r--r--tests/io/buffered_writer.py6
-rw-r--r--tests/io/buffered_writer.py.exp1
-rw-r--r--tests/io/bytesio_ext.py4
-rw-r--r--tests/io/resource_stream.py15
-rw-r--r--tests/io/resource_stream.py.exp2
-rw-r--r--tests/micropython/const_intbig.py13
-rw-r--r--tests/micropython/const_intbig.py.exp2
-rw-r--r--tests/micropython/heapalloc_bytesio.py19
-rw-r--r--tests/micropython/heapalloc_bytesio.py.exp1
-rw-r--r--tests/micropython/heapalloc_exc_raise.py23
-rw-r--r--tests/micropython/heapalloc_exc_raise.py.exp2
-rw-r--r--tests/micropython/heapalloc_int_from_bytes.py9
-rw-r--r--tests/micropython/heapalloc_int_from_bytes.py.exp3
-rw-r--r--tests/micropython/heapalloc_iter.py70
-rw-r--r--tests/micropython/heapalloc_str.py18
-rw-r--r--tests/micropython/heapalloc_str.py.exp0
-rw-r--r--tests/micropython/heapalloc_super.py17
-rw-r--r--tests/micropython/heapalloc_super.py.exp3
-rw-r--r--tests/micropython/heapalloc_traceback.py7
-rw-r--r--tests/micropython/heapalloc_traceback.py.exp2
-rw-r--r--tests/micropython/kbd_intr.py13
-rw-r--r--tests/micropython/kbd_intr.py.exp0
-rw-r--r--tests/micropython/native_const_intbig.py (renamed from tests/micropython/native_const.py)0
-rw-r--r--tests/micropython/native_const_intbig.py.exp (renamed from tests/micropython/native_const.py.exp)0
-rw-r--r--tests/micropython/opt_level.py5
-rw-r--r--tests/micropython/opt_level.py.exp3
-rw-r--r--tests/micropython/schedule.py61
-rw-r--r--tests/micropython/schedule.py.exp4
-rw-r--r--tests/micropython/viper_error.py24
-rw-r--r--tests/micropython/viper_error.py.exp10
-rw-r--r--tests/micropython/viper_misc.py7
-rw-r--r--tests/micropython/viper_misc.py.exp1
-rw-r--r--tests/micropython/viper_misc_intbig.py8
-rw-r--r--tests/micropython/viper_misc_intbig.py.exp1
-rw-r--r--tests/misc/non_compliant.py17
-rw-r--r--tests/misc/non_compliant.py.exp1
-rw-r--r--tests/misc/print_exception.py21
-rw-r--r--tests/misc/recursive_data.py7
-rw-r--r--tests/misc/recursive_iternext.py10
-rw-r--r--tests/pyb/adc.py9
-rw-r--r--tests/pyb/can.py8
-rw-r--r--tests/pyb/dac.py5
-rw-r--r--tests/pyb/extint.py2
-rw-r--r--tests/pyb/extint.py.exp6
-rw-r--r--tests/pyb/pin.py8
-rw-r--r--tests/pyb/pin.py.exp12
-rw-r--r--tests/pyb/pyb1.py7
-rw-r--r--tests/pyb/pyb1.py.exp1
-rw-r--r--tests/pyb/pyb_f405.py11
-rw-r--r--tests/pyb/pyb_f405.py.exp2
-rw-r--r--tests/pyb/pyb_f411.py10
-rw-r--r--tests/pyb/pyb_f411.py.exp1
-rw-r--r--tests/pyb/rtc.py2
-rwxr-xr-xtests/run-tests88
-rw-r--r--tests/thread/stress_create.py22
-rw-r--r--tests/thread/stress_heap.py8
-rw-r--r--tests/thread/thread_exc2.py.exp2
-rw-r--r--tests/thread/thread_lock4.py5
-rw-r--r--tests/thread/thread_qstr1.py8
-rw-r--r--tests/thread/thread_stacksize1.py3
-rw-r--r--tests/unix/extra_coverage.py45
-rw-r--r--tests/unix/extra_coverage.py.exp31
336 files changed, 3990 insertions, 865 deletions
diff --git a/tests/basics/array_q.py b/tests/basics/array_intbig.py
index 2975cd385..4a3b2a0d4 100644
--- a/tests/basics/array_q.py
+++ b/tests/basics/array_intbig.py
@@ -1,4 +1,4 @@
-# test array('q') and array('Q')
+# test array types QqLl that require big-ints
try:
from array import array
@@ -7,6 +7,9 @@ except ImportError:
print("SKIP")
sys.exit()
+print(array('L', [0, 2**32-1]))
+print(array('l', [-2**31, 0, 2**31-1]))
+
print(array('q'))
print(array('Q'))
diff --git a/tests/basics/array_micropython.py b/tests/basics/array_micropython.py
index 8e904bdfe..0c1df0923 100644
--- a/tests/basics/array_micropython.py
+++ b/tests/basics/array_micropython.py
@@ -1,5 +1,10 @@
# test MicroPython-specific features of array.array
-import array
+try:
+ import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
# arrays of objects
a = array.array('O')
diff --git a/tests/basics/attrtuple1.py b/tests/basics/attrtuple1.py
index c4daaaf25..597bfc2a3 100644
--- a/tests/basics/attrtuple1.py
+++ b/tests/basics/attrtuple1.py
@@ -4,6 +4,15 @@
import sys
t = sys.implementation
+# It can be just a normal tuple on small ports
+try:
+ t.name
+except AttributeError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+
# test printing of attrtuple
print(str(t).find("version=") > 0)
diff --git a/tests/basics/boundmeth1.py b/tests/basics/boundmeth1.py
index a72887275..f483ba406 100644
--- a/tests/basics/boundmeth1.py
+++ b/tests/basics/boundmeth1.py
@@ -22,3 +22,9 @@ print(m(1))
# bound method with lots of extra args
m = A().h
print(m(1, 2, 3, 4, 5, 6))
+
+# can't assign attributes to a bound method
+try:
+ A().f.x = 1
+except AttributeError:
+ print('AttributeError')
diff --git a/tests/basics/builtin_abs.py b/tests/basics/builtin_abs.py
index 788bc450f..142344e22 100644
--- a/tests/basics/builtin_abs.py
+++ b/tests/basics/builtin_abs.py
@@ -4,11 +4,3 @@ print(abs(False))
print(abs(True))
print(abs(1))
print(abs(-1))
-
-# bignum
-print(abs(123456789012345678901234567890))
-print(abs(-123456789012345678901234567890))
-
-# edge cases for 32 and 64 bit archs (small int overflow when negating)
-print(abs(-0x3fffffff - 1))
-print(abs(-0x3fffffffffffffff - 1))
diff --git a/tests/basics/builtin_abs_intbig.py b/tests/basics/builtin_abs_intbig.py
new file mode 100644
index 000000000..3dd5ea89f
--- /dev/null
+++ b/tests/basics/builtin_abs_intbig.py
@@ -0,0 +1,9 @@
+# test builtin abs
+
+# bignum
+print(abs(123456789012345678901234567890))
+print(abs(-123456789012345678901234567890))
+
+# edge cases for 32 and 64 bit archs (small int overflow when negating)
+print(abs(-0x3fffffff - 1))
+print(abs(-0x3fffffffffffffff - 1))
diff --git a/tests/basics/builtin_bin.py b/tests/basics/builtin_bin.py
index f6b6079de..85af406ce 100644
--- a/tests/basics/builtin_bin.py
+++ b/tests/basics/builtin_bin.py
@@ -8,5 +8,4 @@ print(bin(-15))
print(bin(12345))
print(bin(0b10101))
-print(bin(12345678901234567890))
print(bin(0b10101010101010101010))
diff --git a/tests/basics/builtin_bin_intbig.py b/tests/basics/builtin_bin_intbig.py
new file mode 100644
index 000000000..345e1f687
--- /dev/null
+++ b/tests/basics/builtin_bin_intbig.py
@@ -0,0 +1,3 @@
+# test builtin bin function
+
+print(bin(12345678901234567890))
diff --git a/tests/basics/builtin_delattr.py b/tests/basics/builtin_delattr.py
index 3743df227..9b38837e4 100644
--- a/tests/basics/builtin_delattr.py
+++ b/tests/basics/builtin_delattr.py
@@ -1,4 +1,10 @@
# test builtin delattr
+try:
+ delattr
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
class A: pass
a = A()
diff --git a/tests/basics/builtin_dir.py b/tests/basics/builtin_dir.py
index 843467e78..16e7e669e 100644
--- a/tests/basics/builtin_dir.py
+++ b/tests/basics/builtin_dir.py
@@ -5,7 +5,7 @@ print('__name__' in dir())
# dir of module
import sys
-print('platform' in dir(sys))
+print('exit' in dir(sys))
# dir of type
print('append' in dir(list))
diff --git a/tests/basics/builtin_divmod.py b/tests/basics/builtin_divmod.py
index c3b865819..26b3ae382 100644
--- a/tests/basics/builtin_divmod.py
+++ b/tests/basics/builtin_divmod.py
@@ -10,18 +10,6 @@ except ZeroDivisionError:
print("ZeroDivisionError")
try:
- divmod(1 << 65, 0)
-except ZeroDivisionError:
- print("ZeroDivisionError")
-
-try:
divmod('a', 'b')
except TypeError:
print("TypeError")
-
-# bignum
-l = (1 << 65) + 123
-print(divmod(3, l))
-print(divmod(l, 5))
-print(divmod(l + 3, l))
-print(divmod(l * 20, l + 2))
diff --git a/tests/basics/builtin_divmod_intbig.py b/tests/basics/builtin_divmod_intbig.py
new file mode 100644
index 000000000..758e83415
--- /dev/null
+++ b/tests/basics/builtin_divmod_intbig.py
@@ -0,0 +1,13 @@
+# test builtin divmod
+
+try:
+ divmod(1 << 65, 0)
+except ZeroDivisionError:
+ print("ZeroDivisionError")
+
+# bignum
+l = (1 << 65) + 123
+print(divmod(3, l))
+print(divmod(l, 5))
+print(divmod(l + 3, l))
+print(divmod(l * 20, l + 2))
diff --git a/tests/basics/builtin_hash.py b/tests/basics/builtin_hash.py
index ffea08e57..704895fbb 100644
--- a/tests/basics/builtin_hash.py
+++ b/tests/basics/builtin_hash.py
@@ -4,8 +4,6 @@ print(hash(False))
print(hash(True))
print({():1}) # hash tuple
print({(1,):1}) # hash non-empty tuple
-print({1 << 66:1}) # hash big int
-print({-(1 << 66):2}) # hash negative big int
print(hash in {hash:1}) # hash function
try:
@@ -50,9 +48,3 @@ class E:
def __hash__(self):
return True
print(hash(E()))
-
-# __hash__ returning a large number should be truncated
-class F:
- def __hash__(self):
- return 1 << 70 | 1
-print(hash(F()) != 0)
diff --git a/tests/basics/builtin_hash_intbig.py b/tests/basics/builtin_hash_intbig.py
new file mode 100644
index 000000000..0092c0f3a
--- /dev/null
+++ b/tests/basics/builtin_hash_intbig.py
@@ -0,0 +1,10 @@
+# test builtin hash function
+
+print({1 << 66:1}) # hash big int
+print({-(1 << 66):2}) # hash negative big int
+
+# __hash__ returning a large number should be truncated
+class F:
+ def __hash__(self):
+ return 1 << 70 | 1
+print(hash(F()) != 0)
diff --git a/tests/basics/builtin_help.py b/tests/basics/builtin_help.py
new file mode 100644
index 000000000..d554f308d
--- /dev/null
+++ b/tests/basics/builtin_help.py
@@ -0,0 +1,18 @@
+# test builtin help function
+
+try:
+ help
+except NameError:
+ print("SKIP")
+ import sys
+ sys.exit()
+
+help() # no args
+help(help) # help for a function
+help(int) # help for a class
+help(1) # help for an instance
+import micropython
+help(micropython) # help for a module
+help('modules') # list available modules
+
+print('done') # so last bit of output is predictable
diff --git a/tests/basics/builtin_help.py.exp b/tests/basics/builtin_help.py.exp
new file mode 100644
index 000000000..ed8a7d74b
--- /dev/null
+++ b/tests/basics/builtin_help.py.exp
@@ -0,0 +1,14 @@
+########
+object <function> is of type function
+object <class 'int'> is of type type
+ from_bytes -- <classmethod>
+ to_bytes -- <function>
+object 1 is of type int
+ from_bytes -- <classmethod>
+ to_bytes -- <function>
+object <module 'micropython'> is of type module
+ __name__ -- micropython
+ const -- <function>
+ opt_level -- <function>
+########
+done
diff --git a/tests/basics/builtin_hex.py b/tests/basics/builtin_hex.py
index 7d1c98a7a..95d74257e 100644
--- a/tests/basics/builtin_hex.py
+++ b/tests/basics/builtin_hex.py
@@ -7,6 +7,3 @@ print(hex(-15))
print(hex(12345))
print(hex(0x12345))
-
-print(hex(12345678901234567890))
-print(hex(0x12345678901234567890))
diff --git a/tests/basics/builtin_hex_intbig.py b/tests/basics/builtin_hex_intbig.py
new file mode 100644
index 000000000..7049ca3f5
--- /dev/null
+++ b/tests/basics/builtin_hex_intbig.py
@@ -0,0 +1,4 @@
+# test builtin hex function
+
+print(hex(12345678901234567890))
+print(hex(0x12345678901234567890))
diff --git a/tests/basics/builtin_minmax.py b/tests/basics/builtin_minmax.py
index d395d4421..a925b3fe9 100644
--- a/tests/basics/builtin_minmax.py
+++ b/tests/basics/builtin_minmax.py
@@ -1,4 +1,11 @@
# test builtin min and max functions
+try:
+ min
+ max
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
print(min(0,1))
print(min(1,0))
diff --git a/tests/basics/builtin_oct.py b/tests/basics/builtin_oct.py
index d8ba8e434..6dc48a6fa 100644
--- a/tests/basics/builtin_oct.py
+++ b/tests/basics/builtin_oct.py
@@ -7,6 +7,3 @@ print(oct(-15))
print(oct(12345))
print(oct(0o12345))
-
-print(oct(12345678901234567890))
-print(oct(0o12345670123456701234))
diff --git a/tests/basics/builtin_oct_intbig.py b/tests/basics/builtin_oct_intbig.py
new file mode 100644
index 000000000..4dc28ab46
--- /dev/null
+++ b/tests/basics/builtin_oct_intbig.py
@@ -0,0 +1,4 @@
+# test builtin oct function
+
+print(oct(12345678901234567890))
+print(oct(0o12345670123456701234))
diff --git a/tests/basics/builtin_override.py b/tests/basics/builtin_override.py
index e245985ad..f3632e59a 100644
--- a/tests/basics/builtin_override.py
+++ b/tests/basics/builtin_override.py
@@ -3,7 +3,13 @@
import builtins
# override generic builtin
-builtins.abs = lambda x: x + 1
+try:
+ builtins.abs = lambda x: x + 1
+except AttributeError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
print(abs(1))
# __build_class__ is handled in a special way
diff --git a/tests/basics/builtin_pow.py b/tests/basics/builtin_pow.py
index a19ab8c84..5012a76be 100644
--- a/tests/basics/builtin_pow.py
+++ b/tests/basics/builtin_pow.py
@@ -1,11 +1,7 @@
# test builtin pow() with integral values
-
# 2 arg version
+
print(pow(0, 1))
print(pow(1, 0))
print(pow(-2, 3))
print(pow(3, 8))
-
-# 3 arg version
-print(pow(3, 4, 7))
-
diff --git a/tests/basics/builtin_pow3.py b/tests/basics/builtin_pow3.py
new file mode 100644
index 000000000..dec7253bb
--- /dev/null
+++ b/tests/basics/builtin_pow3.py
@@ -0,0 +1,25 @@
+# test builtin pow() with integral values
+# 3 arg version
+
+try:
+ print(pow(3, 4, 7))
+except NotImplementedError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+# 3 arg pow is defined to only work on integers
+try:
+ print(pow("x", 5, 6))
+except TypeError:
+ print("TypeError expected")
+
+try:
+ print(pow(4, "y", 6))
+except TypeError:
+ print("TypeError expected")
+
+try:
+ print(pow(4, 5, "z"))
+except TypeError:
+ print("TypeError expected")
diff --git a/tests/basics/builtin_pow3_intbig.py b/tests/basics/builtin_pow3_intbig.py
new file mode 100644
index 000000000..9f482cbde
--- /dev/null
+++ b/tests/basics/builtin_pow3_intbig.py
@@ -0,0 +1,23 @@
+# test builtin pow() with integral values
+# 3 arg version
+
+try:
+ print(pow(3, 4, 7))
+except NotImplementedError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+print(pow(555557, 1000002, 1000003))
+
+# Tests for 3 arg pow with large values
+
+# This value happens to be prime
+x = 0xd48a1e2a099b1395895527112937a391d02d4a208bce5d74b281cf35a57362502726f79a632f063a83c0eba66196712d963aa7279ab8a504110a668c0fc38a7983c51e6ee7a85cae87097686ccdc359ee4bbf2c583bce524e3f7836bded1c771a4efcb25c09460a862fc98e18f7303df46aaeb34da46b0c4d61d5cd78350f3edb60e6bc4befa712a849
+y = 0x3accf60bb1a5365e4250d1588eb0fe6cd81ad495e9063f90880229f2a625e98c59387238670936afb2cafc5b79448e4414d6cd5e9901aa845aa122db58ddd7b9f2b17414600a18c47494ed1f3d49d005a5
+
+print(hex(pow(2, 200, x))) # Should not overflow, just 1 << 200
+print(hex(pow(2, x-1, x))) # Should be 1, since x is prime
+print(hex(pow(y, x-1, x))) # Should be 1, since x is prime
+print(hex(pow(y, y-1, x))) # Should be a 'big value'
+print(hex(pow(y, y-1, y))) # Should be a 'big value'
diff --git a/tests/basics/builtin_property.py b/tests/basics/builtin_property.py
index 403abd62f..ff4ff073c 100644
--- a/tests/basics/builtin_property.py
+++ b/tests/basics/builtin_property.py
@@ -1,4 +1,10 @@
# test builtin property
+try:
+ property
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
# create a property object explicitly
property()
diff --git a/tests/basics/builtin_range.py b/tests/basics/builtin_range.py
index 59fc0344a..0e2fabd82 100644
--- a/tests/basics/builtin_range.py
+++ b/tests/basics/builtin_range.py
@@ -33,11 +33,16 @@ print(range(1, 4)[0:])
print(range(1, 4)[1:])
print(range(1, 4)[:-1])
print(range(7, -2, -4)[:])
+print(range(1, 100, 5)[5:15:3])
+print(range(1, 100, 5)[15:5:-3])
+print(range(100, 1, -5)[5:15:3])
+print(range(100, 1, -5)[15:5:-3])
-# attrs
-print(range(1, 2, 3).start)
-print(range(1, 2, 3).stop)
-print(range(1, 2, 3).step)
+# zero step
+try:
+ range(1, 2, 0)
+except ValueError:
+ print("ValueError")
# bad unary op
try:
@@ -50,9 +55,3 @@ try:
range(1)[0] = 1
except TypeError:
print("TypeError")
-
-# bad attr (can't store)
-try:
- range(4).start = 0
-except AttributeError:
- print('AttributeError')
diff --git a/tests/basics/builtin_range_attrs.py b/tests/basics/builtin_range_attrs.py
new file mode 100644
index 000000000..9327c802a
--- /dev/null
+++ b/tests/basics/builtin_range_attrs.py
@@ -0,0 +1,19 @@
+# test attributes of builtin range type
+
+try:
+ range(0).start
+except AttributeError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+# attrs
+print(range(1, 2, 3).start)
+print(range(1, 2, 3).stop)
+print(range(1, 2, 3).step)
+
+# bad attr (can't store)
+try:
+ range(4).start = 0
+except AttributeError:
+ print('AttributeError')
diff --git a/tests/basics/builtin_reversed.py b/tests/basics/builtin_reversed.py
index f129a4f5d..59e9c7821 100644
--- a/tests/basics/builtin_reversed.py
+++ b/tests/basics/builtin_reversed.py
@@ -1,4 +1,10 @@
# test the builtin reverse() function
+try:
+ reversed
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
# list
print(list(reversed([])))
diff --git a/tests/basics/builtin_sorted.py b/tests/basics/builtin_sorted.py
index a4f71a15e..68855b61b 100644
--- a/tests/basics/builtin_sorted.py
+++ b/tests/basics/builtin_sorted.py
@@ -1,4 +1,11 @@
# test builtin sorted
+try:
+ sorted
+ set
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
print(sorted(set(range(100))))
print(sorted(set(range(100)), key=lambda x: x + 100*(x % 2)))
diff --git a/tests/basics/bytearray_construct.py b/tests/basics/bytearray_construct.py
index 1c45f6fcf..9c8f3adaa 100644
--- a/tests/basics/bytearray_construct.py
+++ b/tests/basics/bytearray_construct.py
@@ -1,12 +1,6 @@
# test construction of bytearray from different objects
-from array import array
-
# bytes, tuple, list
print(bytearray(b'123'))
print(bytearray((1, 2)))
print(bytearray([1, 2]))
-
-# arrays
-print(bytearray(array('b', [1, 2])))
-print(bytearray(array('h', [0x101, 0x202])))
diff --git a/tests/basics/bytearray_construct_array.py b/tests/basics/bytearray_construct_array.py
new file mode 100644
index 000000000..6d45cafda
--- /dev/null
+++ b/tests/basics/bytearray_construct_array.py
@@ -0,0 +1,11 @@
+# test construction of bytearray from different objects
+try:
+ from array import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+# arrays
+print(bytearray(array('b', [1, 2])))
+print(bytearray(array('h', [0x101, 0x202])))
diff --git a/tests/basics/bytearray_construct_endian.py b/tests/basics/bytearray_construct_endian.py
index dbd635c0c..f68f9b89d 100644
--- a/tests/basics/bytearray_construct_endian.py
+++ b/tests/basics/bytearray_construct_endian.py
@@ -1,6 +1,10 @@
# test construction of bytearray from different objects
-
-from array import array
+try:
+ from array import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
# arrays
print(bytearray(array('h', [1, 2])))
diff --git a/tests/basics/bytearray_longint.py b/tests/basics/bytearray_intbig.py
index 334eabe12..334eabe12 100644
--- a/tests/basics/bytearray_longint.py
+++ b/tests/basics/bytearray_intbig.py
diff --git a/tests/basics/bytearray_slice_assign.py b/tests/basics/bytearray_slice_assign.py
index 510e784da..c4b5c43e3 100644
--- a/tests/basics/bytearray_slice_assign.py
+++ b/tests/basics/bytearray_slice_assign.py
@@ -51,6 +51,11 @@ b = bytearray(10)
b[:-1] = bytearray(500)
print(len(b), b[0], b[-1])
+# extension with self on RHS
+b = bytearray(x)
+b[4:] = b
+print(b)
+
# Assignment of bytes to array slice
b = bytearray(2)
b[1:1] = b"12345"
diff --git a/tests/basics/bytes_add.py b/tests/basics/bytes_add.py
index 7a887db23..ebccf0662 100644
--- a/tests/basics/bytes_add.py
+++ b/tests/basics/bytes_add.py
@@ -3,9 +3,6 @@
print(b"123" + b"456")
print(b"123" + bytearray(2))
-import array
-
-# should be byteorder-neutral
-print(b"123" + array.array('h', [0x1515]))
-
-print(b"\x01\x02" + array.array('b', [1, 2]))
+print(b"123" + b"") # RHS is empty, can be optimised
+print(b"" + b"123") # LHS is empty, can be optimised
+print(b"" + bytearray(1)) # LHS is empty but can't be optimised
diff --git a/tests/basics/bytes_add_array.py b/tests/basics/bytes_add_array.py
new file mode 100644
index 000000000..2b8cbccef
--- /dev/null
+++ b/tests/basics/bytes_add_array.py
@@ -0,0 +1,12 @@
+# test bytes + other
+try:
+ import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+# should be byteorder-neutral
+print(b"123" + array.array('h', [0x1515]))
+
+print(b"\x01\x02" + array.array('b', [1, 2]))
diff --git a/tests/basics/bytes_add_endian.py b/tests/basics/bytes_add_endian.py
index 5471280d9..1bbd0f2c3 100644
--- a/tests/basics/bytes_add_endian.py
+++ b/tests/basics/bytes_add_endian.py
@@ -1,5 +1,9 @@
# test bytes + other
-
-import array
+try:
+ import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
print(b"123" + array.array('i', [1]))
diff --git a/tests/basics/bytes_compare2.py b/tests/basics/bytes_compare2.py
index 8959da3ae..4d5de21d2 100644
--- a/tests/basics/bytes_compare2.py
+++ b/tests/basics/bytes_compare2.py
@@ -3,9 +3,3 @@ print(b"123" == bytearray(b"123"))
print(b'123' < bytearray(b"124"))
print(b'123' > bytearray(b"122"))
print(bytearray(b"23") in b"1234")
-
-import array
-
-print(array.array('b', [1, 2]) in b'\x01\x02\x03')
-# CPython gives False here
-#print(b"\x01\x02\x03" == array.array("B", [1, 2, 3]))
diff --git a/tests/basics/bytes_compare_array.py b/tests/basics/bytes_compare_array.py
new file mode 100644
index 000000000..ad41d1d37
--- /dev/null
+++ b/tests/basics/bytes_compare_array.py
@@ -0,0 +1,10 @@
+try:
+ import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+print(array.array('b', [1, 2]) in b'\x01\x02\x03')
+# CPython gives False here
+#print(b"\x01\x02\x03" == array.array("B", [1, 2, 3]))
diff --git a/tests/basics/bytes_construct.py b/tests/basics/bytes_construct.py
index 59e02f063..0d638c08f 100644
--- a/tests/basics/bytes_construct.py
+++ b/tests/basics/bytes_construct.py
@@ -1,19 +1,10 @@
# test construction of bytes from different objects
-from array import array
-
# tuple, list, bytearray
print(bytes((1, 2)))
print(bytes([1, 2]))
print(bytes(bytearray(4)))
-# arrays
-print(bytes(array('b', [1, 2])))
-print(bytes(array('h', [0x101, 0x202])))
-
-# long ints
-print(ord(bytes([14953042807679334000 & 0xff])))
-
# constructor value out of range
try:
bytes([-1])
diff --git a/tests/basics/bytes_construct_array.py b/tests/basics/bytes_construct_array.py
new file mode 100644
index 000000000..72c2d0c58
--- /dev/null
+++ b/tests/basics/bytes_construct_array.py
@@ -0,0 +1,11 @@
+# test construction of bytes from different objects
+try:
+ from array import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+# arrays
+print(bytes(array('b', [1, 2])))
+print(bytes(array('h', [0x101, 0x202])))
diff --git a/tests/basics/bytes_construct_endian.py b/tests/basics/bytes_construct_endian.py
index 1912f63a4..77e0eaaa5 100644
--- a/tests/basics/bytes_construct_endian.py
+++ b/tests/basics/bytes_construct_endian.py
@@ -1,6 +1,11 @@
# test construction of bytes from different objects
-from array import array
+try:
+ from array import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
# arrays
print(bytes(array('h', [1, 2])))
diff --git a/tests/basics/bytes_construct_intbig.py b/tests/basics/bytes_construct_intbig.py
new file mode 100644
index 000000000..c32de185f
--- /dev/null
+++ b/tests/basics/bytes_construct_intbig.py
@@ -0,0 +1,4 @@
+# test construction of bytes from different objects
+
+# long ints
+print(ord(bytes([14953042807679334000 & 0xff])))
diff --git a/tests/basics/class_delattr_setattr.py b/tests/basics/class_delattr_setattr.py
new file mode 100644
index 000000000..0d061aee6
--- /dev/null
+++ b/tests/basics/class_delattr_setattr.py
@@ -0,0 +1,63 @@
+# test __delattr__ and __setattr__
+
+# feature test for __setattr__/__delattr__
+try:
+ class Test():
+ def __delattr__(self, attr): pass
+ del Test().noexist
+except AttributeError:
+ import sys
+ print('SKIP')
+ sys.exit()
+
+# this class just prints the calls to see if they were executed
+class A():
+ def __getattr__(self, attr):
+ print('get', attr)
+ return 1
+ def __setattr__(self, attr, val):
+ print('set', attr, val)
+ def __delattr__(self, attr):
+ print('del', attr)
+a = A()
+
+# check basic behaviour
+print(getattr(a, 'foo'))
+setattr(a, 'bar', 2)
+delattr(a, 'baz')
+
+# check meta behaviour
+getattr(a, '__getattr__') # should not call A.__getattr__
+getattr(a, '__setattr__') # should not call A.__getattr__
+getattr(a, '__delattr__') # should not call A.__getattr__
+setattr(a, '__setattr__', 1) # should call A.__setattr__
+delattr(a, '__delattr__') # should call A.__delattr__
+
+# this class acts like a dictionary
+class B:
+ def __init__(self, d):
+ # store the dict in the class, not instance, so
+ # we don't get infinite recursion in __getattr_
+ B.d = d
+
+ def __getattr__(self, attr):
+ if attr in B.d:
+ return B.d[attr]
+ else:
+ raise AttributeError(attr)
+
+ def __setattr__(self, attr, value):
+ B.d[attr] = value
+
+ def __delattr__(self, attr):
+ del B.d[attr]
+
+a = B({"a":1, "b":2})
+print(a.a, a.b)
+a.a = 3
+print(a.a, a.b)
+del a.a
+try:
+ print(a.a)
+except AttributeError:
+ print("AttributeError")
diff --git a/tests/basics/class_descriptor.py b/tests/basics/class_descriptor.py
index 25b373e47..7f295f071 100644
--- a/tests/basics/class_descriptor.py
+++ b/tests/basics/class_descriptor.py
@@ -18,6 +18,13 @@ class Main:
Forward = Descriptor()
m = Main()
+try:
+ m.__class__
+except AttributeError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
r = m.Forward
if 'Descriptor' in repr(r.__class__):
print('SKIP')
diff --git a/tests/basics/class_new.py b/tests/basics/class_new.py
index a6a34c581..0198456b2 100644
--- a/tests/basics/class_new.py
+++ b/tests/basics/class_new.py
@@ -1,3 +1,11 @@
+try:
+ # If we don't expose object.__new__ (small ports), there's
+ # nothing to test.
+ object.__new__
+except AttributeError:
+ import sys
+ print("SKIP")
+ sys.exit()
class A:
def __new__(cls):
print("A.__new__")
diff --git a/tests/basics/class_store_class.py b/tests/basics/class_store_class.py
index 10b94d3c6..00a291586 100644
--- a/tests/basics/class_store_class.py
+++ b/tests/basics/class_store_class.py
@@ -5,7 +5,12 @@
try:
from collections import namedtuple
except ImportError:
- from ucollections import namedtuple
+ try:
+ from ucollections import namedtuple
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
_DefragResultBase = namedtuple('DefragResult', [ 'foo', 'bar' ])
diff --git a/tests/basics/class_super.py b/tests/basics/class_super.py
index 4b052d8f3..1338ef452 100644
--- a/tests/basics/class_super.py
+++ b/tests/basics/class_super.py
@@ -20,3 +20,17 @@ class A:
def p(self):
print(str(super())[:18])
A().p()
+
+
+# test compiler's handling of long expressions with super
+class A:
+ bar = 123
+ def foo(self):
+ print('A foo')
+ return [1, 2, 3]
+class B(A):
+ def foo(self):
+ print('B foo')
+ print(super().bar) # accessing attribute after super()
+ return super().foo().count(2) # calling a subsequent method
+print(B().foo())
diff --git a/tests/basics/class_super_aslocal.py b/tests/basics/class_super_aslocal.py
new file mode 100644
index 000000000..c9259110a
--- /dev/null
+++ b/tests/basics/class_super_aslocal.py
@@ -0,0 +1,9 @@
+# test using the name "super" as a local variable
+
+class A:
+ def foo(self):
+ super = [1, 2]
+ super.pop()
+ print(super)
+
+A().foo()
diff --git a/tests/basics/class_super_closure.py b/tests/basics/class_super_closure.py
new file mode 100644
index 000000000..41acae90d
--- /dev/null
+++ b/tests/basics/class_super_closure.py
@@ -0,0 +1,18 @@
+# test that no-arg super() works when self is closed over
+
+class A:
+ def __init__(self):
+ self.val = 4
+ def foo(self):
+ # we access a member of self to check that self is correct
+ return list(range(self.val))
+class B(A):
+ def foo(self):
+ # self is closed over because it's referenced in the list comprehension
+ # and then super() must detect this and load from the closure cell
+ return [self.bar(i) for i in super().foo()]
+ def bar(self, x):
+ return 2 * x
+
+print(A().foo())
+print(B().foo())
diff --git a/tests/basics/class_super_object.py b/tests/basics/class_super_object.py
index 21b97328e..a841d34ab 100644
--- a/tests/basics/class_super_object.py
+++ b/tests/basics/class_super_object.py
@@ -1,4 +1,12 @@
# Calling object.__init__() via super().__init__
+try:
+ # If we don't expose object.__init__ (small ports), there's
+ # nothing to test.
+ object.__init__
+except AttributeError:
+ import sys
+ print("SKIP")
+ sys.exit()
class Test(object):
def __init__(self):
diff --git a/tests/basics/comprehension1.py b/tests/basics/comprehension1.py
index 7f541ee53..892d6b4e3 100644
--- a/tests/basics/comprehension1.py
+++ b/tests/basics/comprehension1.py
@@ -14,7 +14,6 @@ def f():
print(d[0], d[1], d[2], d[3], d[4])
# set comprehension
-
- print({a for a in range(5)})
+ # see set_comprehension.py
f()
diff --git a/tests/basics/containment.py b/tests/basics/containment.py
index f8be04e92..bae366113 100644
--- a/tests/basics/containment.py
+++ b/tests/basics/containment.py
@@ -1,5 +1,6 @@
+# sets, see set_containment
for i in 1, 2:
- for o in {1:2}, {1}, {1:2}.keys():
+ for o in {1:2}, {1:2}.keys():
print("{} in {}: {}".format(i, o, i in o))
print("{} not in {}: {}".format(i, o, i not in o))
diff --git a/tests/basics/dict_fromkeys.py b/tests/basics/dict_fromkeys.py
index bfad347c8..7b11319a2 100644
--- a/tests/basics/dict_fromkeys.py
+++ b/tests/basics/dict_fromkeys.py
@@ -7,7 +7,3 @@ d = dict.fromkeys([1, 2, 3, 4], 42)
l = list(d.values())
l.sort()
print(l)
-
-# argument to fromkeys has no __len__
-d = dict.fromkeys(reversed(range(1)))
-print(d)
diff --git a/tests/basics/dict_fromkeys2.py b/tests/basics/dict_fromkeys2.py
new file mode 100644
index 000000000..7ea0cc5b3
--- /dev/null
+++ b/tests/basics/dict_fromkeys2.py
@@ -0,0 +1,11 @@
+try:
+ reversed
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+# argument to fromkeys has no __len__
+d = dict.fromkeys(reversed(range(1)))
+#d = dict.fromkeys((x for x in range(1)))
+print(d)
diff --git a/tests/basics/enumerate.py b/tests/basics/enumerate.py
index 00595cb0f..3cc1350a0 100644
--- a/tests/basics/enumerate.py
+++ b/tests/basics/enumerate.py
@@ -1,3 +1,10 @@
+try:
+ enumerate
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
+
print(list(enumerate([])))
print(list(enumerate([1, 2, 3])))
print(list(enumerate([1, 2, 3], 5)))
diff --git a/tests/basics/filter.py b/tests/basics/filter.py
index 5883e3d00..d0b36733c 100644
--- a/tests/basics/filter.py
+++ b/tests/basics/filter.py
@@ -1,2 +1,9 @@
+try:
+ filter
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
+
print(list(filter(lambda x: x & 1, range(-3, 4))))
print(list(filter(None, range(-3, 4))))
diff --git a/tests/basics/floordivide.py b/tests/basics/floordivide.py
index 930313d6c..60e7634b1 100644
--- a/tests/basics/floordivide.py
+++ b/tests/basics/floordivide.py
@@ -12,18 +12,3 @@ print(a // b)
print(a // -b)
print(-a // b)
print(-a // -b)
-
-if True:
- a = 987654321987987987987987987987
- b = 19
-
- print(a // b)
- print(a // -b)
- print(-a // b)
- print(-a // -b)
- a = 10000000000000000000000000000000000000000000
- b = 100
- print(a // b)
- print(a // -b)
- print(-a // b)
- print(-a // -b)
diff --git a/tests/basics/floordivide_intbig.py b/tests/basics/floordivide_intbig.py
new file mode 100644
index 000000000..422329fcd
--- /dev/null
+++ b/tests/basics/floordivide_intbig.py
@@ -0,0 +1,15 @@
+# check modulo matches python definition
+
+a = 987654321987987987987987987987
+b = 19
+
+print(a // b)
+print(a // -b)
+print(-a // b)
+print(-a // -b)
+a = 10000000000000000000000000000000000000000000
+b = 100
+print(a // b)
+print(a // -b)
+print(-a // b)
+print(-a // -b)
diff --git a/tests/basics/for_range.py b/tests/basics/for_range.py
index 58a8f7caa..fc736277d 100644
--- a/tests/basics/for_range.py
+++ b/tests/basics/for_range.py
@@ -6,6 +6,13 @@ for x in range(*(1, 3)):
for x in range(1, *(6, 2)):
print(x)
+# zero step
+try:
+ for x in range(1, 2, 0):
+ pass
+except ValueError:
+ print('ValueError')
+
# apply args using **
try:
for x in range(**{'end':1}):
diff --git a/tests/basics/fun_calldblstar3.py b/tests/basics/fun_calldblstar3.py
index 4367e68df..b796d52c7 100644
--- a/tests/basics/fun_calldblstar3.py
+++ b/tests/basics/fun_calldblstar3.py
@@ -5,7 +5,8 @@ def foo(**kw):
class Mapping:
def keys(self):
- return ['a', 'b', 'c']
+ # the long string checks the case of string interning
+ return ['a', 'b', 'c', 'abcdefghijklmnopqrst']
def __getitem__(self, key):
if key == 'a':
diff --git a/tests/basics/fun_callstar.py b/tests/basics/fun_callstar.py
index 2275d3d4f..a27a288a3 100644
--- a/tests/basics/fun_callstar.py
+++ b/tests/basics/fun_callstar.py
@@ -17,6 +17,11 @@ foo(*range(3))
# pos then iterator
foo(1, *range(2, 4))
+# an iterator with many elements
+def foo(*rest):
+ print(rest)
+foo(*range(10))
+
# method calls with *pos
class A:
diff --git a/tests/basics/fun_error.py b/tests/basics/fun_error.py
index 305b24911..367fe0b7f 100644
--- a/tests/basics/fun_error.py
+++ b/tests/basics/fun_error.py
@@ -27,8 +27,5 @@ test_exc("[].sort(1)", TypeError)
# function with keyword args given extra keyword args
test_exc("[].sort(noexist=1)", TypeError)
-# function with keyword args not given a specific keyword arg
-test_exc("enumerate()", TypeError)
-
# kw given for positional, but a different positional is missing
test_exc("def f(x, y): pass\nf(x=1)", TypeError)
diff --git a/tests/basics/fun_error2.py b/tests/basics/fun_error2.py
new file mode 100644
index 000000000..c4d2c0b64
--- /dev/null
+++ b/tests/basics/fun_error2.py
@@ -0,0 +1,19 @@
+# test errors from bad function calls
+try:
+ enumerate
+except:
+ print("SKIP")
+ import sys
+ sys.exit()
+
+def test_exc(code, exc):
+ try:
+ exec(code)
+ print("no exception")
+ except exc:
+ print("right exception")
+ except:
+ print("wrong exception")
+
+# function with keyword args not given a specific keyword arg
+test_exc("enumerate()", TypeError)
diff --git a/tests/basics/gen_yield_from_close.py b/tests/basics/gen_yield_from_close.py
index d66691ff9..833986105 100644
--- a/tests/basics/gen_yield_from_close.py
+++ b/tests/basics/gen_yield_from_close.py
@@ -102,7 +102,7 @@ except RuntimeError:
# case where close is propagated up to a built-in iterator
def gen8():
- g = reversed([2, 1])
+ g = range(2)
yield from g
g = gen8()
print(next(g))
diff --git a/tests/basics/gen_yield_from_throw2.py b/tests/basics/gen_yield_from_throw2.py
index 2cff9e08b..0abfdd8cc 100644
--- a/tests/basics/gen_yield_from_throw2.py
+++ b/tests/basics/gen_yield_from_throw2.py
@@ -1,5 +1,5 @@
-# uPy differs from CPython for this test
-# generator ignored GeneratorExit
+# generator ignores a thrown GeneratorExit (this is allowed)
+
def gen():
try:
yield 123
@@ -7,9 +7,12 @@ def gen():
print('GeneratorExit')
yield 456
+# thrown a class
g = gen()
print(next(g))
-try:
- g.throw(GeneratorExit)
-except RuntimeError:
- print('RuntimeError')
+print(g.throw(GeneratorExit))
+
+# thrown an instance
+g = gen()
+print(next(g))
+print(g.throw(GeneratorExit()))
diff --git a/tests/basics/gen_yield_from_throw2.py.exp b/tests/basics/gen_yield_from_throw2.py.exp
deleted file mode 100644
index d5805b494..000000000
--- a/tests/basics/gen_yield_from_throw2.py.exp
+++ /dev/null
@@ -1,3 +0,0 @@
-123
-GeneratorExit
-RuntimeError
diff --git a/tests/basics/gen_yield_from_throw3.py b/tests/basics/gen_yield_from_throw3.py
new file mode 100644
index 000000000..0f6c7c842
--- /dev/null
+++ b/tests/basics/gen_yield_from_throw3.py
@@ -0,0 +1,30 @@
+# yield-from a user-defined generator with a throw() method
+
+class Iter:
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ return 1
+
+ def throw(self, x):
+ print('throw', x)
+ return 456
+
+def gen():
+ yield from Iter()
+
+# calling close() should not call throw()
+g = gen()
+print(next(g))
+g.close()
+
+# can throw a non-exception object
+g = gen()
+print(next(g))
+print(g.throw(123))
+
+# throwing an exception class just injects that class
+g = gen()
+print(next(g))
+print(g.throw(ZeroDivisionError))
diff --git a/tests/basics/int_mpz.py b/tests/basics/int_big1.py
index 425bc21b6..425bc21b6 100644
--- a/tests/basics/int_mpz.py
+++ b/tests/basics/int_big1.py
diff --git a/tests/basics/int_bytes.py b/tests/basics/int_bytes.py
index 2f468da44..93c00bba1 100644
--- a/tests/basics/int_bytes.py
+++ b/tests/basics/int_bytes.py
@@ -1,7 +1,10 @@
print((10).to_bytes(1, "little"))
print((111111).to_bytes(4, "little"))
print((100).to_bytes(10, "little"))
-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"))
+
+# check that extra zero bytes don't change the internal int value
+print(int.from_bytes(bytes(20), "little") == 0)
+print(int.from_bytes(b"\x01" + bytes(20), "little") == 1)
diff --git a/tests/basics/int_bytes_intbig.py b/tests/basics/int_bytes_intbig.py
new file mode 100644
index 000000000..0e0ad1cbb
--- /dev/null
+++ b/tests/basics/int_bytes_intbig.py
@@ -0,0 +1,12 @@
+print((2**64).to_bytes(9, "little"))
+
+b = bytes(range(20))
+
+il = int.from_bytes(b, "little")
+ib = int.from_bytes(b, "big")
+print(il)
+print(ib)
+print(il.to_bytes(20, "little"))
+
+# check that extra zero bytes don't change the internal int value
+print(int.from_bytes(b + bytes(10), "little") == int.from_bytes(b, "little"))
diff --git a/tests/basics/int_bytes_notimpl.py b/tests/basics/int_bytes_notimpl.py
index b47d6ab58..b149f4496 100644
--- a/tests/basics/int_bytes_notimpl.py
+++ b/tests/basics/int_bytes_notimpl.py
@@ -2,8 +2,3 @@ try:
print((10).to_bytes(1, "big"))
except Exception as e:
print(type(e))
-
-try:
- print(int.from_bytes(b"\0", "big"))
-except Exception as e:
- print(type(e))
diff --git a/tests/basics/int_bytes_notimpl.py.exp b/tests/basics/int_bytes_notimpl.py.exp
index d1bf338eb..606649a69 100644
--- a/tests/basics/int_bytes_notimpl.py.exp
+++ b/tests/basics/int_bytes_notimpl.py.exp
@@ -1,2 +1 @@
<class 'NotImplementedError'>
-<class 'NotImplementedError'>
diff --git a/tests/basics/int_constfolding.py b/tests/basics/int_constfolding.py
index aa38fa6b8..7bb538378 100644
--- a/tests/basics/int_constfolding.py
+++ b/tests/basics/int_constfolding.py
@@ -7,19 +7,11 @@ print(+100)
# negation
print(-1)
print(-(-1))
-print(-0x3fffffff) # 32-bit edge case
-print(-0x3fffffffffffffff) # 64-bit edge case
-print(-(-0x3fffffff - 1)) # 32-bit edge case
-print(-(-0x3fffffffffffffff - 1)) # 64-bit edge case
# 1's complement
print(~0)
print(~1)
print(~-1)
-print(~0x3fffffff) # 32-bit edge case
-print(~0x3fffffffffffffff) # 64-bit edge case
-print(~(-0x3fffffff - 1)) # 32-bit edge case
-print(~(-0x3fffffffffffffff - 1)) # 64-bit edge case
# addition
print(1 + 2)
@@ -37,9 +29,3 @@ print(123 // 7, 123 % 7)
print(-123 // 7, -123 % 7)
print(123 // -7, 123 % -7)
print(-123 // -7, -123 % -7)
-
-# zero big-num on rhs
-print(1 + ((1 << 65) - (1 << 65)))
-
-# negative big-num on rhs
-print(1 + (-(1 << 65)))
diff --git a/tests/basics/int_constfolding_intbig.py b/tests/basics/int_constfolding_intbig.py
new file mode 100644
index 000000000..714f1559a
--- /dev/null
+++ b/tests/basics/int_constfolding_intbig.py
@@ -0,0 +1,19 @@
+# tests int constant folding in compiler
+
+# negation
+print(-0x3fffffff) # 32-bit edge case
+print(-0x3fffffffffffffff) # 64-bit edge case
+print(-(-0x3fffffff - 1)) # 32-bit edge case
+print(-(-0x3fffffffffffffff - 1)) # 64-bit edge case
+
+# 1's complement
+print(~0x3fffffff) # 32-bit edge case
+print(~0x3fffffffffffffff) # 64-bit edge case
+print(~(-0x3fffffff - 1)) # 32-bit edge case
+print(~(-0x3fffffffffffffff - 1)) # 64-bit edge case
+
+# zero big-num on rhs
+print(1 + ((1 << 65) - (1 << 65)))
+
+# negative big-num on rhs
+print(1 + (-(1 << 65)))
diff --git a/tests/basics/int_divmod.py b/tests/basics/int_divmod.py
index 3c76cd958..2e878135f 100644
--- a/tests/basics/int_divmod.py
+++ b/tests/basics/int_divmod.py
@@ -5,11 +5,3 @@ for i in range(-2, 3):
for j in range(-4, 5):
if j != 0:
print(i, j, i // j, i % j, divmod(i, j))
-
-# this tests bignum modulo
-a = 987654321987987987987987987987
-b = 19
-print(a % b)
-print(a % -b)
-print(-a % b)
-print(-a % -b)
diff --git a/tests/basics/int_divmod_intbig.py b/tests/basics/int_divmod_intbig.py
new file mode 100644
index 000000000..ea8de07f2
--- /dev/null
+++ b/tests/basics/int_divmod_intbig.py
@@ -0,0 +1,9 @@
+# test integer floor division and modulo
+
+# this tests bignum modulo
+a = 987654321987987987987987987987
+b = 19
+print(a % b)
+print(a % -b)
+print(-a % b)
+print(-a % -b)
diff --git a/tests/basics/int_long.py b/tests/basics/int_intbig.py
index a22075d1f..a22075d1f 100644
--- a/tests/basics/int_long.py
+++ b/tests/basics/int_intbig.py
diff --git a/tests/basics/iter0.py b/tests/basics/iter0.py
index 6110e8fa5..d20ade7fe 100644
--- a/tests/basics/iter0.py
+++ b/tests/basics/iter0.py
@@ -4,3 +4,6 @@ try:
pass
except TypeError:
print('TypeError')
+
+# builtin type that is iterable, calling __next__ explicitly
+print(iter(range(4)).__next__())
diff --git a/tests/basics/iter_of_iter.py b/tests/basics/iter_of_iter.py
index 70282aa97..d775b6a44 100644
--- a/tests/basics/iter_of_iter.py
+++ b/tests/basics/iter_of_iter.py
@@ -4,5 +4,4 @@ i = iter(iter([1, 2, 3]))
print(list(i))
i = iter(iter({1:2, 3:4, 5:6}))
print(sorted(i))
-i = iter(iter({1, 2, 3}))
-print(sorted(i))
+# set, see set_iter_of_iter.py
diff --git a/tests/basics/lexer.py b/tests/basics/lexer.py
index 5f12afa70..244de8cb9 100644
--- a/tests/basics/lexer.py
+++ b/tests/basics/lexer.py
@@ -9,6 +9,14 @@ exec("\n")
exec("\n\n")
exec("\r")
exec("\r\r")
+exec("\t")
+exec("\r\n")
+exec("\nprint(1)")
+exec("\rprint(2)")
+exec("\r\nprint(3)")
+exec("\n5")
+exec("\r6")
+exec("\r\n7")
print(eval("1"))
print(eval("12"))
print(eval("123"))
@@ -19,6 +27,14 @@ print(eval("1\r"))
print(eval("12\r"))
print(eval("123\r"))
+# line continuation
+print(eval("'123' \\\r '456'"))
+print(eval("'123' \\\n '456'"))
+print(eval("'123' \\\r\n '456'"))
+print(eval("'123'\\\r'456'"))
+print(eval("'123'\\\n'456'"))
+print(eval("'123'\\\r\n'456'"))
+
# backslash used to escape a line-break in a string
print('a\
b')
diff --git a/tests/basics/list_slice_3arg.py b/tests/basics/list_slice_3arg.py
index 8578d5855..a5eda8034 100644
--- a/tests/basics/list_slice_3arg.py
+++ b/tests/basics/list_slice_3arg.py
@@ -26,3 +26,14 @@ print(x[-1:-1:-1])
print(x[-1:-2:-1])
print(x[-1:-11:-1])
print(x[-10:-11:-1])
+print(x[:-15:-1])
+
+# test negative indices that are out-of-bounds
+print([][::-1])
+print([1][::-1])
+print([][0:-10:-1])
+print([1][0:-10:-1])
+print([][:-20:-1])
+print([1][:-20:-1])
+print([][-20::-1])
+print([1][-20::-1])
diff --git a/tests/basics/list_slice_assign.py b/tests/basics/list_slice_assign.py
index baa9a0081..1ad1ef27c 100644
--- a/tests/basics/list_slice_assign.py
+++ b/tests/basics/list_slice_assign.py
@@ -34,3 +34,14 @@ print(l)
l = list(x)
del l[:-3]
print(l)
+
+# assign a tuple
+l = [1, 2, 3]
+l[0:1] = (10, 11, 12)
+print(l)
+
+# RHS of slice must be an iterable
+try:
+ [][0:1] = 123
+except TypeError:
+ print('TypeError')
diff --git a/tests/basics/list_slice_assign_grow.py b/tests/basics/list_slice_assign_grow.py
index 12b1541e3..fa256235f 100644
--- a/tests/basics/list_slice_assign_grow.py
+++ b/tests/basics/list_slice_assign_grow.py
@@ -26,3 +26,8 @@ print(l)
l = list(x)
l[100:100] = [10, 20, 30, 40]
print(l)
+
+# growing by using itself on RHS
+l = list(range(10))
+l[4:] = l
+print(l)
diff --git a/tests/basics/map.py b/tests/basics/map.py
index 62dca44ed..8fce352c2 100644
--- a/tests/basics/map.py
+++ b/tests/basics/map.py
@@ -1,4 +1,4 @@
print(list(map(lambda x: x & 1, range(-3, 4))))
print(list(map(abs, range(-3, 4))))
-print(list(map(set, [[i] for i in range(-3, 4)])))
+print(list(map(tuple, [[i] for i in range(-3, 4)])))
print(list(map(pow, range(4), range(4))))
diff --git a/tests/basics/memoryview1.py b/tests/basics/memoryview1.py
index 1cd411195..a771acdda 100644
--- a/tests/basics/memoryview1.py
+++ b/tests/basics/memoryview1.py
@@ -1,4 +1,10 @@
# test memoryview
+try:
+ memoryview
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
# test reading from bytes
b = b'1234'
@@ -12,6 +18,10 @@ try:
m[0] = 1
except TypeError:
print("TypeError")
+try:
+ m[0:2] = b'00'
+except TypeError:
+ print("TypeError")
# test writing to bytearray
b = bytearray(b)
diff --git a/tests/basics/memoryview2.py b/tests/basics/memoryview2.py
index 5117d7a68..4b5af852b 100644
--- a/tests/basics/memoryview2.py
+++ b/tests/basics/memoryview2.py
@@ -1,13 +1,14 @@
# test memoryview accessing maximum values for signed/unsigned elements
-
-from array import array
+try:
+ from array import array
+ memoryview
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
print(list(memoryview(b'\x7f\x80\x81\xff')))
print(list(memoryview(array('b', [0x7f, -0x80]))))
print(list(memoryview(array('B', [0x7f, 0x80, 0x81, 0xff]))))
print(list(memoryview(array('h', [0x7f00, -0x8000]))))
print(list(memoryview(array('H', [0x7f00, 0x8000, 0x8100, 0xffff]))))
-
-# these constructors give an internal overflow in uPy
-#print(list(memoryview(array('i', [0x7f000000, -0x80000000]))))
-#print(list(memoryview(array('I', [0x7f000000, 0x80000000, 0x81000000, 0xffffffff]))))
diff --git a/tests/basics/memoryview_gc.py b/tests/basics/memoryview_gc.py
index a1e4baad4..9d4857e36 100644
--- a/tests/basics/memoryview_gc.py
+++ b/tests/basics/memoryview_gc.py
@@ -1,4 +1,10 @@
# test memoryview retains pointer to original object/buffer
+try:
+ memoryview
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
b = bytearray(10)
m = memoryview(b)[1:]
diff --git a/tests/basics/memoryview_intbig.py b/tests/basics/memoryview_intbig.py
new file mode 100644
index 000000000..180f15d18
--- /dev/null
+++ b/tests/basics/memoryview_intbig.py
@@ -0,0 +1,11 @@
+# test memoryview accessing maximum values for signed/unsigned elements
+try:
+ from array import array
+ memoryview
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+print(list(memoryview(array('i', [0x7f000000, -0x80000000]))))
+print(list(memoryview(array('I', [0x7f000000, 0x80000000, 0x81000000, 0xffffffff]))))
diff --git a/tests/basics/namedtuple1.py b/tests/basics/namedtuple1.py
index 346e32fbf..132dcf96b 100644
--- a/tests/basics/namedtuple1.py
+++ b/tests/basics/namedtuple1.py
@@ -1,7 +1,12 @@
try:
- from collections import namedtuple
+ try:
+ from collections import namedtuple
+ except ImportError:
+ from ucollections import namedtuple
except ImportError:
- from ucollections import namedtuple
+ import sys
+ print("SKIP")
+ sys.exit()
T = namedtuple("Tup", ["foo", "bar"])
# CPython prints fully qualified name, what we don't bother to do so far
diff --git a/tests/basics/object_new.py b/tests/basics/object_new.py
index befb5bfc2..568feccda 100644
--- a/tests/basics/object_new.py
+++ b/tests/basics/object_new.py
@@ -2,6 +2,14 @@
# (non-initialized) instance of class.
# See e.g. http://infohost.nmt.edu/tcc/help/pubs/python/web/new-new-method.html
# TODO: Find reference in CPython docs
+try:
+ # If we don't expose object.__new__ (small ports), there's
+ # nothing to test.
+ object.__new__
+except AttributeError:
+ import sys
+ print("SKIP")
+ sys.exit()
class Foo:
diff --git a/tests/basics/op_error.py b/tests/basics/op_error.py
index 19ce04bc5..b30b5f0a3 100644
--- a/tests/basics/op_error.py
+++ b/tests/basics/op_error.py
@@ -20,11 +20,9 @@ test_exc("False in True", TypeError)
test_exc("1 * {}", TypeError)
test_exc("1 in 1", TypeError)
test_exc("bytearray() // 2", TypeError)
-test_exc("m = memoryview(bytearray())\nm += bytearray()", TypeError)
# object with buffer protocol needed on rhs
test_exc("bytearray(1) + 1", TypeError)
-test_exc("(1 << 70) in 1", TypeError)
# unsupported subscription
test_exc("1[0]", TypeError)
diff --git a/tests/basics/op_error_intbig.py b/tests/basics/op_error_intbig.py
new file mode 100644
index 000000000..432c05a9f
--- /dev/null
+++ b/tests/basics/op_error_intbig.py
@@ -0,0 +1,13 @@
+# test errors from bad operations (unary, binary, etc)
+
+def test_exc(code, exc):
+ try:
+ exec(code)
+ print("no exception")
+ except exc:
+ print("right exception")
+ except:
+ print("wrong exception")
+
+# object with buffer protocol needed on rhs
+test_exc("(1 << 70) in 1", TypeError)
diff --git a/tests/basics/op_error_memoryview.py b/tests/basics/op_error_memoryview.py
new file mode 100644
index 000000000..658ededc8
--- /dev/null
+++ b/tests/basics/op_error_memoryview.py
@@ -0,0 +1,19 @@
+# test errors from bad operations (unary, binary, etc)
+try:
+ memoryview
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+def test_exc(code, exc):
+ try:
+ exec(code)
+ print("no exception")
+ except exc:
+ print("right exception")
+ except:
+ print("wrong exception")
+
+# unsupported binary operators
+test_exc("m = memoryview(bytearray())\nm += bytearray()", TypeError)
diff --git a/tests/basics/ordereddict1.py b/tests/basics/ordereddict1.py
index 5e8b2413b..7147968c5 100644
--- a/tests/basics/ordereddict1.py
+++ b/tests/basics/ordereddict1.py
@@ -9,8 +9,19 @@ except ImportError:
sys.exit()
d = OrderedDict([(10, 20), ("b", 100), (1, 2)])
+print(len(d))
print(list(d.keys()))
print(list(d.values()))
del d["b"]
+print(len(d))
+print(list(d.keys()))
+print(list(d.values()))
+
+# access remaining elements after deleting
+print(d[10], d[1])
+
+# add an element after deleting
+d["abc"] = 123
+print(len(d))
print(list(d.keys()))
print(list(d.values()))
diff --git a/tests/basics/python34.py b/tests/basics/python34.py
index 7f7a1e015..a23f347d6 100644
--- a/tests/basics/python34.py
+++ b/tests/basics/python34.py
@@ -1,4 +1,4 @@
-# tests that differ when running under Python 3.4 vs 3.5
+# tests that differ when running under Python 3.4 vs 3.5/3.6
# from basics/fun_kwvarargs.py
# test evaluation order of arguments (in 3.4 it's backwards, 3.5 it's fixed)
@@ -13,14 +13,15 @@ f4(*print_ret(['a', 'b']), kw_arg=print_ret(None))
{print_ret(1):print_ret(2)}
# from basics/syntaxerror.py
-# can't have multiple * or ** (in 3.5 we can)
def test_syntax(code):
try:
exec(code)
except SyntaxError:
print("SyntaxError")
-test_syntax("f(*a, *b)")
-test_syntax("f(**a, **b)")
+test_syntax("f(*a, *b)") # can't have multiple * (in 3.5 we can)
+test_syntax("f(**a, **b)") # can't have multiple ** (in 3.5 we can)
+test_syntax("() = []") # can't assign to empty tuple (in 3.6 we can)
+test_syntax("del ()") # can't delete empty tuple (in 3.6 we can)
# from basics/sys1.py
# uPy prints version 3.4
diff --git a/tests/basics/python34.py.exp b/tests/basics/python34.py.exp
index 637f77ce8..f497df3b8 100644
--- a/tests/basics/python34.py.exp
+++ b/tests/basics/python34.py.exp
@@ -5,5 +5,7 @@ None
1
SyntaxError
SyntaxError
+SyntaxError
+SyntaxError
3.4
3 4
diff --git a/tests/basics/set_binop.py b/tests/basics/set_binop.py
index a3657d84b..7848920b6 100644
--- a/tests/basics/set_binop.py
+++ b/tests/basics/set_binop.py
@@ -29,6 +29,25 @@ for s in sets:
print(set('abc') == 1)
+# make sure inplace operators modify the set
+
+s1 = s2 = set('abc')
+s1 |= set('ad')
+print(s1 is s2, len(s1))
+
+s1 = s2 = set('abc')
+s1 ^= set('ad')
+print(s1 is s2, len(s1))
+
+s1 = s2 = set('abc')
+s1 &= set('ad')
+print(s1 is s2, len(s1))
+
+s1 = s2 = set('abc')
+s1 -= set('ad')
+print(s1 is s2, len(s1))
+
+# unsupported operator
try:
set('abc') * 2
except TypeError:
diff --git a/tests/basics/set_comprehension.py b/tests/basics/set_comprehension.py
new file mode 100644
index 000000000..12a9a29d3
--- /dev/null
+++ b/tests/basics/set_comprehension.py
@@ -0,0 +1 @@
+print({a for a in range(5)})
diff --git a/tests/basics/set_containment.py b/tests/basics/set_containment.py
new file mode 100644
index 000000000..97694f74c
--- /dev/null
+++ b/tests/basics/set_containment.py
@@ -0,0 +1,4 @@
+for i in 1, 2:
+ for o in {}, {1}, {2}:
+ print("{} in {}: {}".format(i, o, i in o))
+ print("{} not in {}: {}".format(i, o, i not in o))
diff --git a/tests/basics/set_iter_of_iter.py b/tests/basics/set_iter_of_iter.py
new file mode 100644
index 000000000..e3e91fa45
--- /dev/null
+++ b/tests/basics/set_iter_of_iter.py
@@ -0,0 +1,2 @@
+i = iter(iter({1, 2, 3}))
+print(sorted(i))
diff --git a/tests/basics/slice_bignum.py b/tests/basics/slice_intbig.py
index cc820522b..cc820522b 100644
--- a/tests/basics/slice_bignum.py
+++ b/tests/basics/slice_intbig.py
diff --git a/tests/basics/special_methods.py b/tests/basics/special_methods.py
index 1df7a7c4c..9f57247c1 100644
--- a/tests/basics/special_methods.py
+++ b/tests/basics/special_methods.py
@@ -105,42 +105,4 @@ cud1 > cud2
cud1 + cud2
cud1 - cud2
-# the following require MICROPY_PY_ALL_SPECIAL_METHODS
-+cud1
--cud1
-~cud1
-cud1 * cud2
-cud1 / cud2
-cud2 // cud1
-cud1 += cud2
-cud1 -= cud2
-
-# TODO: the following operations are not supported on every ports
-#
-# ne is not supported, !(eq) is called instead
-#cud1 != cud2
-#
-# binary and is not supported
-# cud1 & cud2
-#
-# binary lshift is not supported
-# cud1<<1
-#
-# modulus is not supported
-# cud1 % 2
-#
-# binary or is not supported
-# cud1 | cud2
-#
-# pow is not supported
-# cud1**2
-#
-# rshift is not suported
-# cud1>>1
-#
-# xor is not supported
-# cud1^cud2
-#
-# in the followin test, cpython still calls __eq__
-# cud3=cud1
-# cud3==cud1
+# more in special_methods2.py
diff --git a/tests/basics/special_methods2.py b/tests/basics/special_methods2.py
new file mode 100644
index 000000000..3623b30dc
--- /dev/null
+++ b/tests/basics/special_methods2.py
@@ -0,0 +1,145 @@
+class Cud():
+
+ def __init__(self):
+ #print("__init__ called")
+ pass
+
+ def __repr__(self):
+ print("__repr__ called")
+ return ""
+
+ def __lt__(self, other):
+ print("__lt__ called")
+
+ def __le__(self, other):
+ print("__le__ called")
+
+ def __eq__(self, other):
+ print("__eq__ called")
+
+ def __ne__(self, other):
+ print("__ne__ called")
+
+ def __ge__(self, other):
+ print("__ge__ called")
+
+ def __gt__(self, other):
+ print("__gt__ called")
+
+ def __abs__(self):
+ print("__abs__ called")
+
+ def __add__(self, other):
+ print("__add__ called")
+
+ def __and__(self, other):
+ print("__and__ called")
+
+ def __floordiv__(self, other):
+ print("__floordiv__ called")
+
+ def __index__(self, other):
+ print("__index__ called")
+
+ def __inv__(self):
+ print("__inv__ called")
+
+ def __invert__(self):
+ print("__invert__ called")
+
+ def __lshift__(self, val):
+ print("__lshift__ called")
+
+ def __mod__(self, val):
+ print("__mod__ called")
+
+ def __mul__(self, other):
+ print("__mul__ called")
+
+ def __matmul__(self, other):
+ print("__matmul__ called")
+
+ def __neg__(self):
+ print("__neg__ called")
+
+ def __or__(self, other):
+ print("__or__ called")
+
+ def __pos__(self):
+ print("__pos__ called")
+
+ def __pow__(self, val):
+ print("__pow__ called")
+
+ def __rshift__(self, val):
+ print("__rshift__ called")
+
+ def __sub__(self, other):
+ print("__sub__ called")
+
+ def __truediv__(self, other):
+ print("__truediv__ called")
+
+ def __div__(self, other):
+ print("__div__ called")
+
+ def __xor__(self, other):
+ print("__xor__ called")
+
+ def __iadd__(self, other):
+ print("__iadd__ called")
+ return self
+
+ def __isub__(self, other):
+ print("__isub__ called")
+ return self
+
+cud1 = Cud()
+cud2 = Cud()
+
+try:
+ +cud1
+except TypeError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+# the following require MICROPY_PY_ALL_SPECIAL_METHODS
++cud1
+-cud1
+~cud1
+cud1 * cud2
+cud1 / cud2
+cud2 // cud1
+cud1 += cud2
+cud1 -= cud2
+
+# TODO: the following operations are not supported on every ports
+#
+# ne is not supported, !(eq) is called instead
+#cud1 != cud2
+#
+# binary and is not supported
+# cud1 & cud2
+#
+# binary lshift is not supported
+# cud1<<1
+#
+# modulus is not supported
+# cud1 % 2
+#
+# binary or is not supported
+# cud1 | cud2
+#
+# pow is not supported
+# cud1**2
+#
+# rshift is not suported
+# cud1>>1
+#
+# xor is not supported
+# cud1^cud2
+#
+# in the followin test, cpython still calls __eq__
+# cud3=cud1
+# cud3==cud1
diff --git a/tests/basics/string_format2.py b/tests/basics/string_format2.py
index e211535be..881ff4f80 100644
--- a/tests/basics/string_format2.py
+++ b/tests/basics/string_format2.py
@@ -1,6 +1,6 @@
# comprehensive functionality test for {} format string
-int_tests = False # these take a while, and some give wrong results
+int_tests = False # these take a while
char_tests = True
str_tests = True
diff --git a/tests/basics/string_format_modulo.py b/tests/basics/string_format_modulo.py
index 2e4909220..77bbcfbe3 100644
--- a/tests/basics/string_format_modulo.py
+++ b/tests/basics/string_format_modulo.py
@@ -33,38 +33,11 @@ print("%c" % 48)
print("%c" % 'a')
print("%10s" % 'abc')
print("%-10s" % 'abc')
-print("%d" % 10)
-print("%+d" % 10)
-print("% d" % 10)
-print("%d" % -10)
-print("%d" % True)
-print("%i" % -10)
-print("%i" % True)
-print("%u" % -10)
-print("%u" % True)
-print("%x" % 18)
-print("%o" % 18)
-print("%X" % 18)
-print("%#x" % 18)
-print("%#X" % 18)
-print("%#6o" % 18)
-print("%#6x" % 18)
-print("%#06x" % 18)
-
-print("%*d" % (5, 10))
-print("%*.*d" % (2, 2, 20))
-print("%*.*d" % (5, 8, 20))
-
-print(">%8.4d<" % -12)
-print(">% 8.4d<" % -12)
-print(">%+8.4d<" % 12)
-print(">%+8.4d<" % -12)
-print(">%08.4d<" % -12)
-print(">%08.4d<" % 12)
-print(">%-8.4d<" % -12)
-print(">%-08.4d<" % -12)
-print(">%-+08.4d<" % -12)
-print(">%-+08.4d<" % 12)
+
+# Should be able to print dicts; in this case they aren't used
+# to lookup keywords in formats like %(foo)s
+print('%s' % {})
+print('%s' % ({},))
# Cases when "*" used and there's not enough values total
try:
@@ -77,6 +50,7 @@ except TypeError:
print("TypeError")
print("%(foo)s" % {"foo": "bar", "baz": False})
+print("%s %(foo)s %(foo)s" % {"foo": 1})
try:
print("%(foo)s" % {})
except KeyError:
@@ -87,6 +61,16 @@ try:
except TypeError:
print("TypeError")
+# When using %(foo)s format the single argument must be a dict
+try:
+ '%(foo)s' % 1
+except TypeError:
+ print('TypeError')
+try:
+ '%(foo)s' % ({},)
+except TypeError:
+ print('TypeError')
+
try:
'%(a' % {'a':1}
except ValueError:
diff --git a/tests/basics/string_format_modulo_int.py b/tests/basics/string_format_modulo_int.py
new file mode 100644
index 000000000..d1f29db22
--- /dev/null
+++ b/tests/basics/string_format_modulo_int.py
@@ -0,0 +1,41 @@
+# test string modulo formatting with int values
+
+# basic cases
+print("%d" % 10)
+print("%+d" % 10)
+print("% d" % 10)
+print("%d" % -10)
+print("%d" % True)
+print("%i" % -10)
+print("%i" % True)
+print("%u" % -10)
+print("%u" % True)
+print("%x" % 18)
+print("%o" % 18)
+print("%X" % 18)
+print("%#x" % 18)
+print("%#X" % 18)
+print("%#6o" % 18)
+print("%#6x" % 18)
+print("%#06x" % 18)
+
+# with *
+print("%*d" % (5, 10))
+print("%*.*d" % (2, 2, 20))
+print("%*.*d" % (5, 8, 20))
+
+# precision
+for val in (-12, 12):
+ print(">%8.4d<" % val)
+ print(">% 8.4d<" % val)
+ print(">%+8.4d<" % val)
+ print(">%08.4d<" % val)
+ print(">%-8.4d<" % val)
+ print(">%-08.4d<" % val)
+ print(">%-+08.4d<" % val)
+
+# test + option with various amount of padding
+for pad in ('', ' ', '0'):
+ for n in (1, 2, 3):
+ for val in (-1, 0, 1):
+ print(('%+' + pad + str(n) + 'd') % val)
diff --git a/tests/basics/string_join.py b/tests/basics/string_join.py
index b8694c01e..82f1b799a 100644
--- a/tests/basics/string_join.py
+++ b/tests/basics/string_join.py
@@ -14,6 +14,11 @@ print(','.join('abc' for i in range(5)))
print(b','.join([b'abc', b'123']))
try:
+ ''.join(None)
+except TypeError:
+ print("TypeError")
+
+try:
print(b','.join(['abc', b'123']))
except TypeError:
print("TypeError")
@@ -25,3 +30,13 @@ except TypeError:
# joined by the compiler
print("a" "b")
+print("a" '''b''')
+print("a" # inline comment
+ "b")
+print("a" \
+ "b")
+
+# the following should not be joined by the compiler
+x = 'a'
+'b'
+print(x)
diff --git a/tests/basics/struct1.py b/tests/basics/struct1.py
index d89519a2f..bb6877c78 100644
--- a/tests/basics/struct1.py
+++ b/tests/basics/struct1.py
@@ -37,34 +37,6 @@ s = struct.pack("BHBI", 10, 100, 200, 300)
v = struct.unpack("BHBI", s)
print(v == (10, 100, 200, 300))
-# check maximum pack on 32-bit machine
-print(struct.pack("<I", 2**32 - 1))
-print(struct.pack("<I", 0xffffffff))
-
-# long long ints
-print(struct.pack("<Q", 2**64 - 1))
-print(struct.pack(">Q", 2**64 - 1))
-print(struct.pack("<Q", 0xffffffffffffffff))
-print(struct.pack(">Q", 0xffffffffffffffff))
-print(struct.pack("<q", -1))
-print(struct.pack(">q", -1))
-print(struct.pack("<Q", 1234567890123456789))
-print(struct.pack("<q", -1234567890123456789))
-print(struct.pack(">Q", 1234567890123456789))
-print(struct.pack(">q", -1234567890123456789))
-print(struct.unpack("<Q", b"\x12\x34\x56\x78\x90\x12\x34\x56"))
-print(struct.unpack(">Q", b"\x12\x34\x56\x78\x90\x12\x34\x56"))
-print(struct.unpack("<q", b"\x12\x34\x56\x78\x90\x12\x34\xf6"))
-print(struct.unpack(">q", b"\xf2\x34\x56\x78\x90\x12\x34\x56"))
-
-# check maximum unpack
-print(struct.unpack("<I", b"\xff\xff\xff\xff"))
-print(struct.unpack("<Q", b"\xff\xff\xff\xff\xff\xff\xff\xff"))
-
-# check small int overflow
-print(struct.unpack("<i", b'\xff\xff\xff\x7f'))
-print(struct.unpack("<q", b'\xff\xff\xff\xff\xff\xff\xff\x7f'))
-
# network byte order
print(struct.pack('!i', 123))
diff --git a/tests/basics/struct1_intbig.py b/tests/basics/struct1_intbig.py
new file mode 100644
index 000000000..7f4c3ce12
--- /dev/null
+++ b/tests/basics/struct1_intbig.py
@@ -0,0 +1,37 @@
+try:
+ import ustruct as struct
+except:
+ try:
+ import struct
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+# check maximum pack on 32-bit machine
+print(struct.pack("<I", 2**32 - 1))
+print(struct.pack("<I", 0xffffffff))
+
+# long long ints
+print(struct.pack("<Q", 2**64 - 1))
+print(struct.pack(">Q", 2**64 - 1))
+print(struct.pack("<Q", 0xffffffffffffffff))
+print(struct.pack(">Q", 0xffffffffffffffff))
+print(struct.pack("<q", -1))
+print(struct.pack(">q", -1))
+print(struct.pack("<Q", 1234567890123456789))
+print(struct.pack("<q", -1234567890123456789))
+print(struct.pack(">Q", 1234567890123456789))
+print(struct.pack(">q", -1234567890123456789))
+print(struct.unpack("<Q", b"\x12\x34\x56\x78\x90\x12\x34\x56"))
+print(struct.unpack(">Q", b"\x12\x34\x56\x78\x90\x12\x34\x56"))
+print(struct.unpack("<q", b"\x12\x34\x56\x78\x90\x12\x34\xf6"))
+print(struct.unpack(">q", b"\xf2\x34\x56\x78\x90\x12\x34\x56"))
+
+# check maximum unpack
+print(struct.unpack("<I", b"\xff\xff\xff\xff"))
+print(struct.unpack("<Q", b"\xff\xff\xff\xff\xff\xff\xff\xff"))
+
+# check small int overflow
+print(struct.unpack("<i", b'\xff\xff\xff\x7f'))
+print(struct.unpack("<q", b'\xff\xff\xff\xff\xff\xff\xff\x7f'))
diff --git a/tests/basics/struct2.py b/tests/basics/struct2.py
index 6dd963260..e3f8bbebf 100644
--- a/tests/basics/struct2.py
+++ b/tests/basics/struct2.py
@@ -26,7 +26,17 @@ print(struct.calcsize('0s1s0H2H'))
print(struct.unpack('<0s1s0H2H', b'01234'))
print(struct.pack('<0s1s0H2H', b'abc', b'abc', 258, 515))
-# check that zero of an unknown type raises an exception
+# check that unknown types raise an exception
+try:
+ struct.unpack('z', b'1')
+except:
+ print('Exception')
+
+try:
+ struct.pack('z', (b'1',))
+except:
+ print('Exception')
+
try:
struct.calcsize('0z')
except:
diff --git a/tests/basics/struct_micropython.py b/tests/basics/struct_micropython.py
index e3b0ea508..53306dad6 100644
--- a/tests/basics/struct_micropython.py
+++ b/tests/basics/struct_micropython.py
@@ -18,3 +18,16 @@ o = A()
s = struct.pack("<O", o)
o2 = struct.unpack("<O", s)
print(o is o2[0])
+
+# pack and unpack pointer to a string
+# This requires uctypes to get the address of the string and instead of
+# putting this in a dedicated test that can be skipped we simply pass
+# if the import fails.
+try:
+ import uctypes
+ o = uctypes.addressof('abc')
+ s = struct.pack("<S", o)
+ o2 = struct.unpack("<S", s)
+ assert o2[0] == 'abc'
+except ImportError:
+ pass
diff --git a/tests/basics/subclass_classmethod.py b/tests/basics/subclass_classmethod.py
index ae5fbd1aa..48f164b36 100644
--- a/tests/basics/subclass_classmethod.py
+++ b/tests/basics/subclass_classmethod.py
@@ -5,6 +5,13 @@ class Base:
def foo(cls):
print(cls.__name__)
+try:
+ Base.__name__
+except AttributeError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
class Sub(Base):
pass
diff --git a/tests/basics/syntaxerror.py b/tests/basics/syntaxerror.py
index e5cbbac06..4161de017 100644
--- a/tests/basics/syntaxerror.py
+++ b/tests/basics/syntaxerror.py
@@ -46,9 +46,6 @@ test_syntax("f**2 = 1")
# can't assign to power of composite
test_syntax("f[0]**2 = 1")
-# can't assign to empty tuple
-test_syntax("() = 1")
-
# can't have *x on RHS
test_syntax("x = *x")
@@ -66,7 +63,6 @@ test_syntax("[a, b] += c")
test_syntax("def f(a=1, b): pass")
# can't delete these things
-test_syntax("del ()")
test_syntax("del f()")
test_syntax("del f[0]**2")
test_syntax("del (a for a in a)")
diff --git a/tests/basics/sys1.py b/tests/basics/sys1.py
index 816c8823a..29ef974d1 100644
--- a/tests/basics/sys1.py
+++ b/tests/basics/sys1.py
@@ -6,8 +6,18 @@ print(sys.__name__)
print(type(sys.path))
print(type(sys.argv))
print(sys.byteorder in ('little', 'big'))
-print(sys.maxsize > 100)
-print(sys.implementation.name in ('cpython', 'micropython'))
+
+try:
+ print(sys.maxsize > 100)
+except AttributeError:
+ # Effectively skip subtests
+ print(True)
+
+try:
+ print(sys.implementation.name in ('cpython', 'micropython'))
+except AttributeError:
+ # Effectively skip subtests
+ print(True)
try:
sys.exit()
diff --git a/tests/basics/try_finally_loops.py b/tests/basics/try_finally_loops.py
index 06a6b4a0c..a4b80196f 100644
--- a/tests/basics/try_finally_loops.py
+++ b/tests/basics/try_finally_loops.py
@@ -41,3 +41,28 @@ for i in [1]:
break
finally:
print('finally 4')
+
+# Test unwind-jump where there is nothing in the body of the try or finally.
+# This checks that the bytecode emitter allocates enough stack for the unwind.
+for i in [1]:
+ try:
+ break
+ finally:
+ pass
+
+# The following test checks that the globals dict is valid after a call to a
+# function that has an unwind jump.
+# There was a bug where an unwind jump would trash the globals dict upon return
+# from a function, because it used the Python-stack incorrectly.
+def f():
+ for i in [1]:
+ try:
+ break
+ finally:
+ pass
+def g():
+ global global_var
+ f()
+ print(global_var)
+global_var = 'global'
+g()
diff --git a/tests/basics/tuple1.py b/tests/basics/tuple1.py
index 2993391d5..a7956c107 100644
--- a/tests/basics/tuple1.py
+++ b/tests/basics/tuple1.py
@@ -17,6 +17,10 @@ print(x[2:3])
print(x + (10, 100, 10000))
+# inplace add operator
+x += (10, 11, 12)
+print(x)
+
# construction of tuple from large iterator (tests implementation detail of uPy)
print(tuple(range(20)))
diff --git a/tests/basics/unpack1.py b/tests/basics/unpack1.py
index 0e8ec592c..1e8b53aa1 100644
--- a/tests/basics/unpack1.py
+++ b/tests/basics/unpack1.py
@@ -41,7 +41,7 @@ a, *b, c = 24, 25, 26, 27 ; print(a, b)
a = [28, 29]
*b, = a
-print(a, b, a == b)
+print(a, b, a == b, a is b)
[*a] = [1, 2, 3]
print(a)
diff --git a/tests/basics/zip.py b/tests/basics/zip.py
index c0109094f..958addb7a 100644
--- a/tests/basics/zip.py
+++ b/tests/basics/zip.py
@@ -1,2 +1,10 @@
+try:
+ zip
+ set
+except NameError:
+ print("SKIP")
+ import sys
+ sys.exit()
+
print(list(zip()))
-print(list(zip([1], {2,3})))
+print(list(zip([1], set([2, 3]))))
diff --git a/tests/cmdline/cmd_parsetree.py.exp b/tests/cmdline/cmd_parsetree.py.exp
index 06fbeadfc..d9f81d8d4 100644
--- a/tests/cmdline/cmd_parsetree.py.exp
+++ b/tests/cmdline/cmd_parsetree.py.exp
@@ -1,28 +1,28 @@
----------------
-[ 4] rule(2) (n=8)
- tok(5)
-[ 4] rule(78) (n=4)
+[ 4] rule(1) (n=8)
+ tok(4)
+[ 4] rule(22) (n=4)
id(i)
-[ 4] rule(131) (n=1)
+[ 4] rule(44) (n=1)
NULL
-[ 5] rule(42) (n=0)
+[ 5] rule(8) (n=0)
NULL
-[ 6] rule(32) (n=2)
+[ 6] rule(5) (n=2)
id(a)
- tok(15)
-[ 7] rule(32) (n=2)
+ tok(14)
+[ 7] rule(5) (n=2)
id(b)
str(str)
-[ 8] rule(32) (n=2)
+[ 8] rule(5) (n=2)
id(c)
-[ 8] literal str(a very long str that will not be interned)
-[ 9] rule(32) (n=2)
+[ 8] literal \.\+
+[ 9] rule(5) (n=2)
id(d)
bytes(bytes)
-[ 10] rule(32) (n=2)
+[ 10] rule(5) (n=2)
id(e)
-[ 10] literal bytes(a very long bytes that will not be interned)
-[ 11] rule(32) (n=2)
+[ 10] literal \.\+
+[ 11] rule(5) (n=2)
id(f)
[ 11] literal \.\+
----------------
@@ -31,7 +31,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
########
\.\+5b
arg names:
-(N_STATE 2)
+(N_STATE 5)
(N_EXC_STACK 0)
bc=-1 line=1
bc=0 line=4
@@ -43,7 +43,7 @@ arg names:
bc=32 line=10
bc=37 line=11
00 BUILD_TUPLE 0
-02 GET_ITER
+02 GET_ITER_STACK
03 FOR_ITER 12
06 STORE_NAME i
09 JUMP 3
diff --git a/tests/cmdline/cmd_showbc.py b/tests/cmdline/cmd_showbc.py
index 2f4e953bb..6e99fc418 100644
--- a/tests/cmdline/cmd_showbc.py
+++ b/tests/cmdline/cmd_showbc.py
@@ -150,3 +150,7 @@ class Class:
# delete name
del Class
+
+# load super method
+def f(self):
+ super().f()
diff --git a/tests/cmdline/cmd_showbc.py.exp b/tests/cmdline/cmd_showbc.py.exp
index 1f0c054cf..1e015eb03 100644
--- a/tests/cmdline/cmd_showbc.py.exp
+++ b/tests/cmdline/cmd_showbc.py.exp
@@ -7,7 +7,7 @@ arg names:
(N_EXC_STACK 0)
bc=-1 line=1
########
- bc=\\d\+ line=152
+ bc=\\d\+ line=155
00 MAKE_FUNCTION \.\+
\\d\+ STORE_NAME f
\\d\+ MAKE_FUNCTION \.\+
@@ -25,6 +25,8 @@ arg names:
\\d\+ CALL_FUNCTION n=2 nkw=0
\\d\+ STORE_NAME Class
\\d\+ DELETE_NAME Class
+\\d\+ MAKE_FUNCTION \.\+
+\\d\+ STORE_NAME f
\\d\+ LOAD_CONST_NONE
\\d\+ RETURN_VALUE
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes)
@@ -175,14 +177,12 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
\\d\+ LOAD_FAST 15
\\d\+ MAKE_CLOSURE \.\+ 2
\\d\+ LOAD_FAST 2
-\\d\+ GET_ITER
\\d\+ CALL_FUNCTION n=1 nkw=0
\\d\+ STORE_FAST 0
\\d\+ LOAD_FAST 14
\\d\+ LOAD_FAST 15
\\d\+ MAKE_CLOSURE \.\+ 2
\\d\+ LOAD_FAST 2
-\\d\+ GET_ITER
\\d\+ CALL_FUNCTION n=1 nkw=0
\\d\+ STORE_FAST 0
\\d\+ LOAD_FAST 0
@@ -245,7 +245,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
\\d\+ LOAD_FAST 0
\\d\+ STORE_FAST 0
\\d\+ LOAD_DEREF 14
-\\d\+ GET_ITER
+\\d\+ GET_ITER_STACK
\\d\+ FOR_ITER \\d\+
\\d\+ STORE_FAST 0
\\d\+ LOAD_FAST 1
@@ -430,63 +430,85 @@ arg names:
10 STORE_NAME __qualname__
13 LOAD_CONST_NONE
14 RETURN_VALUE
+File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes)
+Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
+########
+\.\+5b
+arg names: self
+(N_STATE 4)
+(N_EXC_STACK 0)
+ bc=-1 line=1
+ bc=0 line=156
+00 LOAD_GLOBAL super (cache=0)
+\\d\+ LOAD_GLOBAL __class__ (cache=0)
+\\d\+ LOAD_FAST 0
+\\d\+ LOAD_SUPER_METHOD f
+\\d\+ CALL_METHOD n=0 nkw=0
+\\d\+ POP_TOP
+\\d\+ LOAD_CONST_NONE
+\\d\+ RETURN_VALUE
File cmdline/cmd_showbc.py, code block '<genexpr>' (descriptor: \.\+, bytecode @\.\+ bytes)
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
########
\.\+5b
arg names: * * *
-(N_STATE 6)
+(N_STATE 9)
(N_EXC_STACK 0)
bc=-\\d\+ line=1
-00 LOAD_FAST 2
-01 FOR_ITER 17
-04 STORE_FAST 3
-05 LOAD_DEREF 1
-07 POP_JUMP_IF_FALSE 1
-10 LOAD_DEREF 0
-12 YIELD_VALUE
-13 POP_TOP
-14 JUMP 1
-17 LOAD_CONST_NONE
-18 RETURN_VALUE
+00 LOAD_NULL
+01 LOAD_FAST 2
+02 LOAD_NULL
+03 LOAD_NULL
+04 FOR_ITER 20
+07 STORE_FAST 3
+08 LOAD_DEREF 1
+10 POP_JUMP_IF_FALSE 4
+13 LOAD_DEREF 0
+15 YIELD_VALUE
+16 POP_TOP
+17 JUMP 4
+20 LOAD_CONST_NONE
+21 RETURN_VALUE
File cmdline/cmd_showbc.py, code block '<listcomp>' (descriptor: \.\+, bytecode @\.\+ bytes)
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
########
\.\+5b
arg names: * * *
-(N_STATE 7)
+(N_STATE 10)
(N_EXC_STACK 0)
bc=-\\d\+ line=1
00 BUILD_LIST 0
02 LOAD_FAST 2
-03 FOR_ITER 19
-06 STORE_FAST 3
-07 LOAD_DEREF 1
-09 POP_JUMP_IF_FALSE 3
-12 LOAD_DEREF 0
-14 STORE_COMP 8
-16 JUMP 3
-19 RETURN_VALUE
+03 GET_ITER_STACK
+04 FOR_ITER 20
+07 STORE_FAST 3
+08 LOAD_DEREF 1
+10 POP_JUMP_IF_FALSE 4
+13 LOAD_DEREF 0
+15 STORE_COMP 20
+17 JUMP 4
+20 RETURN_VALUE
File cmdline/cmd_showbc.py, code block '<dictcomp>' (descriptor: \.\+, bytecode @\.\+ bytes)
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
########
\.\+5b
arg names: * * *
-(N_STATE 8)
+(N_STATE 11)
(N_EXC_STACK 0)
bc=-\\d\+ line=1
########
00 BUILD_MAP 0
02 LOAD_FAST 2
-03 FOR_ITER 21
-06 STORE_FAST 3
-07 LOAD_DEREF 1
-09 POP_JUMP_IF_FALSE 3
-12 LOAD_DEREF 0
-14 LOAD_DEREF 0
-16 STORE_COMP 13
-18 JUMP 3
-21 RETURN_VALUE
+03 GET_ITER_STACK
+04 FOR_ITER 22
+07 STORE_FAST 3
+08 LOAD_DEREF 1
+10 POP_JUMP_IF_FALSE 4
+13 LOAD_DEREF 0
+15 LOAD_DEREF 0
+17 STORE_COMP 25
+19 JUMP 4
+22 RETURN_VALUE
File cmdline/cmd_showbc.py, code block 'closure' (descriptor: \.\+, bytecode @\.\+ bytes)
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
########
diff --git a/tests/cpydiff/core_arguments.py b/tests/cpydiff/core_arguments.py
new file mode 100644
index 000000000..4734a8062
--- /dev/null
+++ b/tests/cpydiff/core_arguments.py
@@ -0,0 +1,10 @@
+"""
+categories: Core
+description: Error messages for methods may display unexpected argument counts
+cause: MicroPython counts "self" as an argument.
+workaround: Interpret error messages with the information above in mind.
+"""
+try:
+ [].append()
+except Exception as e:
+ print(e)
diff --git a/tests/cpydiff/core_class_delnotimpl.py b/tests/cpydiff/core_class_delnotimpl.py
new file mode 100644
index 000000000..c51c3d536
--- /dev/null
+++ b/tests/cpydiff/core_class_delnotimpl.py
@@ -0,0 +1,16 @@
+"""
+categories: Core,Classes
+description: Special method __del__ not implemented for user-defined classes
+cause: Unknown
+workaround: Unknown
+"""
+import gc
+
+class Foo():
+ def __del__(self):
+ print('__del__')
+
+f = Foo()
+del f
+
+gc.collect()
diff --git a/tests/cpydiff/core_class_supermultiple.py b/tests/cpydiff/core_class_supermultiple.py
new file mode 100644
index 000000000..adf4a17a8
--- /dev/null
+++ b/tests/cpydiff/core_class_supermultiple.py
@@ -0,0 +1,27 @@
+"""
+categories: Core,Classes
+description: When inheriting from multiple classes super() only calls one class
+cause: Depth first non-exhaustive method resolution order
+workaround: Unknown
+"""
+class A:
+ def __init__(self):
+ print("A.__init__")
+
+class B(A):
+ def __init__(self):
+ print("B.__init__")
+ super().__init__()
+
+class C(A):
+ def __init__(self):
+ print("C.__init__")
+ super().__init__()
+
+
+class D(B,C):
+ def __init__(self):
+ print("D.__init__")
+ super().__init__()
+
+D()
diff --git a/tests/cpydiff/core_class_superproperty.py b/tests/cpydiff/core_class_superproperty.py
new file mode 100644
index 000000000..1ec210550
--- /dev/null
+++ b/tests/cpydiff/core_class_superproperty.py
@@ -0,0 +1,18 @@
+"""
+categories: Core,Classes
+description: Calling super() getter property in subclass will return a property object, not the value
+cause: Unknown
+workaround: Unknown
+"""
+class A:
+ @property
+ def p(self):
+ return {"a":10}
+
+class AA(A):
+ @property
+ def p(self):
+ return super().p
+
+a = AA()
+print(a.p)
diff --git a/tests/cpydiff/core_function_unpacking.py b/tests/cpydiff/core_function_unpacking.py
new file mode 100644
index 000000000..01d25ee4d
--- /dev/null
+++ b/tests/cpydiff/core_function_unpacking.py
@@ -0,0 +1,7 @@
+"""
+categories: Core,Functions
+description: Unpacking function arguments in non-last position isn't detected as an error
+cause: Unknown
+workaround: The syntax below is invalid, never use it in applications.
+"""
+print(*(1, 2), 3)
diff --git a/tests/cpydiff/core_function_userattr.py b/tests/cpydiff/core_function_userattr.py
new file mode 100644
index 000000000..297293908
--- /dev/null
+++ b/tests/cpydiff/core_function_userattr.py
@@ -0,0 +1,11 @@
+"""
+categories: Core,Functions
+description: User-defined attributes for functions are not supported
+cause: MicroPython is highly optimized for memory usage.
+workaround: Use external dictionary, e.g. ``FUNC_X[f] = 0``.
+"""
+def f():
+ pass
+
+f.x = 0
+print(f.x)
diff --git a/tests/cpydiff/core_generator_noexit.py b/tests/cpydiff/core_generator_noexit.py
new file mode 100644
index 000000000..c25fbe75a
--- /dev/null
+++ b/tests/cpydiff/core_generator_noexit.py
@@ -0,0 +1,24 @@
+"""
+categories: Core,Generator
+description: Context manager __exit__() not called in a generator which does not run to completion
+cause: Unknown
+workaround: Unknown
+"""
+class foo(object):
+ def __enter__(self):
+ print('Enter')
+ def __exit__(self, *args):
+ print('Exit')
+
+def bar(x):
+ with foo():
+ while True:
+ x += 1
+ yield x
+
+def func():
+ g = bar(0)
+ for _ in range(3):
+ print(next(g))
+
+func()
diff --git a/tests/cpydiff/core_import_path.py b/tests/cpydiff/core_import_path.py
new file mode 100644
index 000000000..04fc4bd5b
--- /dev/null
+++ b/tests/cpydiff/core_import_path.py
@@ -0,0 +1,9 @@
+"""
+categories: Core,import
+description: __path__ attribute of a package has a different type (single string instead of list of strings) in MicroPython
+cause: MicroPython does't support namespace packages split across filesystem. Beyond that, MicroPython's import system is highly optimized for minimal memory usage.
+workaround: Details of import handling is inherently implementation dependent. Don't rely on such details in portable applications.
+"""
+import modules
+
+print(modules.__path__)
diff --git a/tests/cpydiff/core_import_prereg.py b/tests/cpydiff/core_import_prereg.py
new file mode 100644
index 000000000..4a7121782
--- /dev/null
+++ b/tests/cpydiff/core_import_prereg.py
@@ -0,0 +1,17 @@
+"""
+categories: Core,import
+description: Failed to load modules are still registered as loaded
+cause: To make module handling more efficient, it's not wrapped with exception handling.
+workaround: Test modules before production use; during development, use ``del sys.modules["name"]``, or just soft or hard reset the board.
+"""
+import sys
+
+try:
+ from modules import foo
+except NameError as e:
+ print(e)
+try:
+ from modules import foo
+ print('Should not get here')
+except NameError as e:
+ print(e)
diff --git a/tests/cpydiff/core_import_split_ns_pkgs.py b/tests/cpydiff/core_import_split_ns_pkgs.py
new file mode 100644
index 000000000..700620c47
--- /dev/null
+++ b/tests/cpydiff/core_import_split_ns_pkgs.py
@@ -0,0 +1,14 @@
+"""
+categories: Core,import
+description: MicroPython does't support namespace packages split across filesystem.
+cause: MicroPython's import system is highly optimized for simplicity, minimal memory usage, and minimal filesystem search overhead.
+workaround: Don't install modules belonging to the same namespace package in different directories. For MicroPython, it's recommended to have at most 3-component module search paths: for your current application, per-user (writable), system-wide (non-writable).
+"""
+import sys
+sys.path.append(sys.path[1] + "/modules")
+sys.path.append(sys.path[1] + "/modules2")
+
+import subpkg.foo
+import subpkg.bar
+
+print("Two modules of a split namespace package imported")
diff --git a/tests/cpydiff/core_mro.py b/tests/cpydiff/core_mro.py
new file mode 100644
index 000000000..35b898b30
--- /dev/null
+++ b/tests/cpydiff/core_mro.py
@@ -0,0 +1,15 @@
+"""
+categories: Core
+description: Method Resolution Order (MRO) is not compliant with CPython
+cause: Unknown
+workaround: Unknown
+"""
+class Foo:
+ def __str__(self):
+ return "Foo"
+
+class C(tuple, Foo):
+ pass
+
+t = C((1, 2, 3))
+print(t)
diff --git a/tests/cpydiff/modules/__init__.py b/tests/cpydiff/modules/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/cpydiff/modules/__init__.py
diff --git a/tests/cpydiff/modules/foo.py b/tests/cpydiff/modules/foo.py
new file mode 100644
index 000000000..e6e33a7b4
--- /dev/null
+++ b/tests/cpydiff/modules/foo.py
@@ -0,0 +1,2 @@
+print('foo')
+xxx
diff --git a/tests/cpydiff/modules/subpkg/foo.py b/tests/cpydiff/modules/subpkg/foo.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/cpydiff/modules/subpkg/foo.py
diff --git a/tests/cpydiff/modules2/subpkg/bar.py b/tests/cpydiff/modules2/subpkg/bar.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/cpydiff/modules2/subpkg/bar.py
diff --git a/tests/cpydiff/modules_array_containment.py b/tests/cpydiff/modules_array_containment.py
new file mode 100644
index 000000000..190a3c276
--- /dev/null
+++ b/tests/cpydiff/modules_array_containment.py
@@ -0,0 +1,8 @@
+"""
+categories: Modules,array
+description: Looking for integer not implemented
+cause: Unknown
+workaround: Unknown
+"""
+import array
+print(1 in array.array('B', b'12'))
diff --git a/tests/cpydiff/modules_array_deletion.py b/tests/cpydiff/modules_array_deletion.py
new file mode 100644
index 000000000..97f988da2
--- /dev/null
+++ b/tests/cpydiff/modules_array_deletion.py
@@ -0,0 +1,10 @@
+"""
+categories: Modules,array
+description: Array deletion not implemented
+cause: Unknown
+workaround: Unknown
+"""
+import array
+a = array.array('b', (1, 2, 3))
+del a[1]
+print(a)
diff --git a/tests/cpydiff/modules_array_subscrstep.py b/tests/cpydiff/modules_array_subscrstep.py
new file mode 100644
index 000000000..1103f1826
--- /dev/null
+++ b/tests/cpydiff/modules_array_subscrstep.py
@@ -0,0 +1,9 @@
+"""
+categories: Modules,array
+description: Subscript with step != 1 is not yet implemented
+cause: Unknown
+workaround: Unknown
+"""
+import array
+a = array.array('b', (1, 2, 3))
+print(a[3:2:2])
diff --git a/tests/cpydiff/modules_deque.py b/tests/cpydiff/modules_deque.py
new file mode 100644
index 000000000..dc9369d02
--- /dev/null
+++ b/tests/cpydiff/modules_deque.py
@@ -0,0 +1,9 @@
+"""
+categories: Modules,deque
+description: Deque not implemented
+cause: Unknown
+workaround: Use regular queues or lists creatively
+"""
+import collections
+D = collections.deque()
+print(D)
diff --git a/tests/cpydiff/modules_json_nonserializable.py b/tests/cpydiff/modules_json_nonserializable.py
new file mode 100644
index 000000000..913b734e8
--- /dev/null
+++ b/tests/cpydiff/modules_json_nonserializable.py
@@ -0,0 +1,14 @@
+"""
+categories: Modules,json
+description: JSON module does not throw exception when object is not serialisable
+cause: Unknown
+workaround: Unknown
+"""
+import json
+a = bytes(x for x in range(256))
+try:
+ z = json.dumps(a)
+ x = json.loads(z)
+ print('Should not get here')
+except TypeError:
+ print('TypeError')
diff --git a/tests/cpydiff/modules_struct_fewargs.py b/tests/cpydiff/modules_struct_fewargs.py
new file mode 100644
index 000000000..08d32ca67
--- /dev/null
+++ b/tests/cpydiff/modules_struct_fewargs.py
@@ -0,0 +1,12 @@
+"""
+categories: Modules,struct
+description: Struct pack with too few args, not checked by uPy
+cause: Unknown
+workaround: Unknown
+"""
+import struct
+try:
+ print(struct.pack('bb', 1))
+ print('Should not get here')
+except:
+ print('struct.error')
diff --git a/tests/cpydiff/modules_struct_manyargs.py b/tests/cpydiff/modules_struct_manyargs.py
new file mode 100644
index 000000000..cdbb5c672
--- /dev/null
+++ b/tests/cpydiff/modules_struct_manyargs.py
@@ -0,0 +1,12 @@
+"""
+categories: Modules,struct
+description: Struct pack with too many args, not checked by uPy
+cause: Unknown
+workaround: Unknown
+"""
+import struct
+try:
+ print(struct.pack('bb', 1, 2, 3))
+ print('Should not get here')
+except:
+ print('struct.error')
diff --git a/tests/cpydiff/modules_sys_stdassign.py b/tests/cpydiff/modules_sys_stdassign.py
new file mode 100644
index 000000000..096af430e
--- /dev/null
+++ b/tests/cpydiff/modules_sys_stdassign.py
@@ -0,0 +1,9 @@
+"""
+categories: Modules,sys
+description: Override sys.stdin, sys.stdout and sys.stderr. Impossible as they are stored in read-only memory.
+cause: Unknown
+workaround: Unknown
+"""
+import sys
+sys.stdin = None
+print(sys.stdin)
diff --git a/tests/cpydiff/syntax_spaces.py b/tests/cpydiff/syntax_spaces.py
new file mode 100644
index 000000000..8578a51e2
--- /dev/null
+++ b/tests/cpydiff/syntax_spaces.py
@@ -0,0 +1,18 @@
+"""
+categories: Syntax,Spaces
+description: uPy requires spaces between literal numbers and keywords, CPy doesn't
+cause: Unknown
+workaround: Unknown
+"""
+try:
+ print(eval('1and 0'))
+except SyntaxError:
+ print('Should have worked')
+try:
+ print(eval('1or 0'))
+except SyntaxError:
+ print('Should have worked')
+try:
+ print(eval('1if 1else 0'))
+except SyntaxError:
+ print('Should have worked')
diff --git a/tests/cpydiff/syntax_unicode_nameesc.py b/tests/cpydiff/syntax_unicode_nameesc.py
new file mode 100644
index 000000000..21628c974
--- /dev/null
+++ b/tests/cpydiff/syntax_unicode_nameesc.py
@@ -0,0 +1,7 @@
+"""
+categories: Syntax,Unicode
+description: Unicode name escapes are not implemented
+cause: Unknown
+workaround: Unknown
+"""
+print("\N{LATIN SMALL LETTER A}")
diff --git a/tests/cpydiff/types_bytearray_sliceassign.py b/tests/cpydiff/types_bytearray_sliceassign.py
new file mode 100644
index 000000000..e4068b04b
--- /dev/null
+++ b/tests/cpydiff/types_bytearray_sliceassign.py
@@ -0,0 +1,9 @@
+"""
+categories: Types,bytearray
+description: Array slice assignment with unsupported RHS
+cause: Unknown
+workaround: Unknown
+"""
+b = bytearray(4)
+b[0:1] = [1, 2]
+print(b)
diff --git a/tests/cpydiff/types_bytes_keywords.py b/tests/cpydiff/types_bytes_keywords.py
new file mode 100644
index 000000000..35119e28f
--- /dev/null
+++ b/tests/cpydiff/types_bytes_keywords.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,bytes
+description: bytes(...) with keywords not implemented
+cause: Unknown
+workaround: Input the encoding format directly. eg. ``print(bytes('abc', 'utf-8'))``
+"""
+print(bytes('abc', encoding='utf8'))
diff --git a/tests/cpydiff/types_bytes_subscrstep.py b/tests/cpydiff/types_bytes_subscrstep.py
new file mode 100644
index 000000000..fd1602d65
--- /dev/null
+++ b/tests/cpydiff/types_bytes_subscrstep.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,bytes
+description: Bytes subscr with step != 1 not implemented
+cause: Unknown
+workaround: Unknown
+"""
+print(b'123'[0:3:2])
diff --git a/tests/cpydiff/types_exception_chaining.py b/tests/cpydiff/types_exception_chaining.py
new file mode 100644
index 000000000..836c4eb3e
--- /dev/null
+++ b/tests/cpydiff/types_exception_chaining.py
@@ -0,0 +1,10 @@
+"""
+categories: Types,Exception
+description: Exception chaining not implemented
+cause: Unknown
+workaround: Unknown
+"""
+try:
+ raise TypeError
+except TypeError:
+ raise ValueError
diff --git a/tests/cpydiff/types_exception_instancevar.py b/tests/cpydiff/types_exception_instancevar.py
new file mode 100644
index 000000000..d1015e96c
--- /dev/null
+++ b/tests/cpydiff/types_exception_instancevar.py
@@ -0,0 +1,9 @@
+"""
+categories: Types,Exception
+description: Assign instance variable to exception
+cause: Unknown
+workaround: Unknown
+"""
+e = Exception()
+e.x = 0
+print(e.x)
diff --git a/tests/cpydiff/types_exception_loops.py b/tests/cpydiff/types_exception_loops.py
new file mode 100644
index 000000000..a142e4757
--- /dev/null
+++ b/tests/cpydiff/types_exception_loops.py
@@ -0,0 +1,12 @@
+"""
+categories: Types,Exception
+description: While loop guards will obscure exception line number reporting due to being optimised onto the end of the code block
+cause: Unknown
+workaround: Unknown
+"""
+l = ["-foo", "-bar"]
+
+i = 0
+while l[i][0] == "-":
+ print("iter")
+ i += 1
diff --git a/tests/cpydiff/types_exception_subclassinit.py b/tests/cpydiff/types_exception_subclassinit.py
new file mode 100644
index 000000000..177094646
--- /dev/null
+++ b/tests/cpydiff/types_exception_subclassinit.py
@@ -0,0 +1,11 @@
+"""
+categories: Types,Exception
+description: Exception.__init__ raises TypeError if overridden and called by subclass
+cause: Unknown
+workaround: Unknown
+"""
+class A(Exception):
+ def __init__(self):
+ Exception.__init__(self)
+
+a = A()
diff --git a/tests/cpydiff/types_float_rounding.py b/tests/cpydiff/types_float_rounding.py
new file mode 100644
index 000000000..647f61ba2
--- /dev/null
+++ b/tests/cpydiff/types_float_rounding.py
@@ -0,0 +1,9 @@
+"""
+categories: Types,float
+description: uPy and CPython outputs formats differ
+cause: Unknown
+workaround: Unknown
+"""
+print('%.1g' % -9.9)
+print('%.1e' % 9.99)
+print('%.1e' % 0.999)
diff --git a/tests/cpydiff/types_int_subclassconv.py b/tests/cpydiff/types_int_subclassconv.py
new file mode 100644
index 000000000..565fbad4b
--- /dev/null
+++ b/tests/cpydiff/types_int_subclassconv.py
@@ -0,0 +1,11 @@
+"""
+categories: Types,int
+description: No int conversion for int-derived types available
+cause: Unknown
+workaround: Unknown
+"""
+class A(int):
+ __add__ = lambda self, other: A(int(self) + other)
+
+a = A(42)
+print(a+a)
diff --git a/tests/cpydiff/types_int_tobytesfloat.py b/tests/cpydiff/types_int_tobytesfloat.py
new file mode 100644
index 000000000..5d5b980fa
--- /dev/null
+++ b/tests/cpydiff/types_int_tobytesfloat.py
@@ -0,0 +1,10 @@
+"""
+categories: Types,int
+description: Incorrect error message when passing float into to_bytes
+cause: Unknown
+workaround: Unknown
+"""
+try:
+ int('1').to_bytes(1.0)
+except TypeError as e:
+ print(e)
diff --git a/tests/cpydiff/types_list_delete_subscrstep.py b/tests/cpydiff/types_list_delete_subscrstep.py
new file mode 100644
index 000000000..f524fa8dc
--- /dev/null
+++ b/tests/cpydiff/types_list_delete_subscrstep.py
@@ -0,0 +1,9 @@
+"""
+categories: Types,list
+description: List delete with step != 1 not implemented
+cause: Unknown
+workaround: Unknown
+"""
+l = [1, 2, 3, 4]
+del l[0:4:2]
+print(l)
diff --git a/tests/cpydiff/types_list_store_noniter.py b/tests/cpydiff/types_list_store_noniter.py
new file mode 100644
index 000000000..1d69b4a82
--- /dev/null
+++ b/tests/cpydiff/types_list_store_noniter.py
@@ -0,0 +1,9 @@
+"""
+categories: Types,list
+description: List slice-store with non-iterable on RHS is not implemented
+cause: RHS is restricted to be a tuple or list
+workaround: Use ``list(<iter>)`` on RHS to convert the iterable to a list
+"""
+l = [10, 20]
+l[0:1] = range(4)
+print(l)
diff --git a/tests/cpydiff/types_list_store_subscrstep.py b/tests/cpydiff/types_list_store_subscrstep.py
new file mode 100644
index 000000000..2de2e1a3c
--- /dev/null
+++ b/tests/cpydiff/types_list_store_subscrstep.py
@@ -0,0 +1,9 @@
+"""
+categories: Types,list
+description: List store with step != 1 not implemented
+cause: Unknown
+workaround: Unknown
+"""
+l = [1, 2, 3, 4]
+l[0:4:2] = [5, 6]
+print(l)
diff --git a/tests/cpydiff/types_str_decodeerror.py b/tests/cpydiff/types_str_decodeerror.py
new file mode 100644
index 000000000..944db98fe
--- /dev/null
+++ b/tests/cpydiff/types_str_decodeerror.py
@@ -0,0 +1,11 @@
+"""
+categories: Types,str
+description: UnicodeDecodeError not raised when expected
+cause: Unknown
+workaround: Unknown
+"""
+try:
+ print(repr(str(b"\xa1\x80", 'utf8')))
+ print('Should not get here')
+except UnicodeDecodeError:
+ print('UnicodeDecodeError')
diff --git a/tests/cpydiff/types_str_endswith.py b/tests/cpydiff/types_str_endswith.py
new file mode 100644
index 000000000..ac2600bd2
--- /dev/null
+++ b/tests/cpydiff/types_str_endswith.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,str
+description: Start/end indices such as str.endswith(s, start) not implemented
+cause: Unknown
+workaround: Unknown
+"""
+print('abc'.endswith('c', 1))
diff --git a/tests/cpydiff/types_str_formatsubscr.py b/tests/cpydiff/types_str_formatsubscr.py
new file mode 100644
index 000000000..dd1d8d33d
--- /dev/null
+++ b/tests/cpydiff/types_str_formatsubscr.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,str
+description: Attributes/subscr not implemented
+cause: Unknown
+workaround: Unknown
+"""
+print('{a[0]}'.format(a=[1, 2]))
diff --git a/tests/cpydiff/types_str_keywords.py b/tests/cpydiff/types_str_keywords.py
new file mode 100644
index 000000000..b336b1a73
--- /dev/null
+++ b/tests/cpydiff/types_str_keywords.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,str
+description: str(...) with keywords not implemented
+cause: Unknown
+workaround: Input the encoding format directly. eg ``print(bytes('abc', 'utf-8'))``
+"""
+print(str(b'abc', encoding='utf8'))
diff --git a/tests/cpydiff/types_str_rsplitnone.py b/tests/cpydiff/types_str_rsplitnone.py
new file mode 100644
index 000000000..cadf86987
--- /dev/null
+++ b/tests/cpydiff/types_str_rsplitnone.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,str
+description: None as first argument for rsplit such as str.rsplit(None, n) not implemented
+cause: Unknown
+workaround: Unknown
+"""
+print('a a a'.rsplit(None, 1))
diff --git a/tests/cpydiff/types_str_subclassequality.py b/tests/cpydiff/types_str_subclassequality.py
new file mode 100644
index 000000000..8aec1ea78
--- /dev/null
+++ b/tests/cpydiff/types_str_subclassequality.py
@@ -0,0 +1,11 @@
+"""
+categories: Types,str
+description: Instance of a subclass of str cannot be compared for equality with an instance of a str
+cause: Unknown
+workaround: Unknown
+"""
+class S(str):
+ pass
+
+s = S('hello')
+print(s == 'hello')
diff --git a/tests/cpydiff/types_str_subscrstep.py b/tests/cpydiff/types_str_subscrstep.py
new file mode 100644
index 000000000..0c2fce1b1
--- /dev/null
+++ b/tests/cpydiff/types_str_subscrstep.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,str
+description: Subscript with step != 1 is not yet implemented
+cause: Unknown
+workaround: Unknown
+"""
+print('abcdefghi'[0:9:2])
diff --git a/tests/cpydiff/types_tuple_subscrstep.py b/tests/cpydiff/types_tuple_subscrstep.py
new file mode 100644
index 000000000..f90f3c5bf
--- /dev/null
+++ b/tests/cpydiff/types_tuple_subscrstep.py
@@ -0,0 +1,7 @@
+"""
+categories: Types,tuple
+description: Tuple load with step != 1 not implemented
+cause: Unknown
+workaround: Unknown
+"""
+print((1, 2, 3, 4)[0:4:2])
diff --git a/tests/extmod/framebuf1.py b/tests/extmod/framebuf1.py
index cdc7e5b18..990b0b120 100644
--- a/tests/extmod/framebuf1.py
+++ b/tests/extmod/framebuf1.py
@@ -7,93 +7,104 @@ except ImportError:
w = 5
h = 16
-buf = bytearray(w * h // 8)
-fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.MVLSB)
-
-# access as buffer
-print(memoryview(fbuf)[0])
-
-# fill
-fbuf.fill(1)
-print(buf)
-fbuf.fill(0)
-print(buf)
-
-# put pixel
-fbuf.pixel(0, 0, 1)
-fbuf.pixel(4, 0, 1)
-fbuf.pixel(0, 15, 1)
-fbuf.pixel(4, 15, 1)
-print(buf)
-
-# clear pixel
-fbuf.pixel(4, 15, 0)
-print(buf)
-
-# get pixel
-print(fbuf.pixel(0, 0), fbuf.pixel(1, 1))
-
-# hline
-fbuf.fill(0)
-fbuf.hline(0, 1, w, 1)
-print('hline', buf)
-
-# vline
-fbuf.fill(0)
-fbuf.vline(1, 0, h, 1)
-print('vline', buf)
-
-# rect
-fbuf.fill(0)
-fbuf.rect(1, 1, 3, 3, 1)
-print('rect', buf)
-
-#fill rect
-fbuf.fill(0)
-fbuf.fill_rect(1, 1, 3, 3, 1)
-print('fill_rect', buf)
-
-# line
-fbuf.fill(0)
-fbuf.line(1, 1, 3, 3, 1)
-print('line', buf)
-
-# line steep negative gradient
-fbuf.fill(0)
-fbuf.line(3, 3, 2, 1, 1)
-print('line', buf)
-
-# scroll
-fbuf.fill(0)
-fbuf.pixel(2, 7, 1)
-fbuf.scroll(0, 1)
-print(buf)
-fbuf.scroll(0, -2)
-print(buf)
-fbuf.scroll(1, 0)
-print(buf)
-fbuf.scroll(-1, 0)
-print(buf)
-fbuf.scroll(2, 2)
-print(buf)
-
-# print text
-fbuf.fill(0)
-fbuf.text("hello", 0, 0, 1)
-print(buf)
-fbuf.text("hello", 0, 0, 0) # clear
-print(buf)
-
-# char out of font range set to chr(127)
-fbuf.text(str(chr(31)), 0, 0)
-print(buf)
-
-# test invalid constructor
+size = w * h // 8
+buf = bytearray(size)
+maps = {framebuf.MONO_VLSB : 'MONO_VLSB',
+ framebuf.MONO_HLSB : 'MONO_HLSB',
+ framebuf.MONO_HMSB : 'MONO_HMSB'}
+
+for mapping in maps.keys():
+ for x in range(size):
+ buf[x] = 0
+ fbuf = framebuf.FrameBuffer(buf, w, h, mapping)
+ print(maps[mapping])
+ # access as buffer
+ print(memoryview(fbuf)[0])
+
+ # fill
+ fbuf.fill(1)
+ print(buf)
+ fbuf.fill(0)
+ print(buf)
+
+ # put pixel
+ fbuf.pixel(0, 0, 1)
+ fbuf.pixel(4, 0, 1)
+ fbuf.pixel(0, 15, 1)
+ fbuf.pixel(4, 15, 1)
+ print(buf)
+
+ # clear pixel
+ fbuf.pixel(4, 15, 0)
+ print(buf)
+
+ # get pixel
+ print(fbuf.pixel(0, 0), fbuf.pixel(1, 1))
+
+ # hline
+ fbuf.fill(0)
+ fbuf.hline(0, 1, w, 1)
+ print('hline', buf)
+
+ # vline
+ fbuf.fill(0)
+ fbuf.vline(1, 0, h, 1)
+ print('vline', buf)
+
+ # rect
+ fbuf.fill(0)
+ fbuf.rect(1, 1, 3, 3, 1)
+ print('rect', buf)
+
+ #fill rect
+ fbuf.fill(0)
+ fbuf.fill_rect(0, 0, 0, 3, 1) # zero width, no-operation
+ fbuf.fill_rect(1, 1, 3, 3, 1)
+ print('fill_rect', buf)
+
+ # line
+ fbuf.fill(0)
+ fbuf.line(1, 1, 3, 3, 1)
+ print('line', buf)
+
+ # line steep negative gradient
+ fbuf.fill(0)
+ fbuf.line(3, 3, 2, 1, 1)
+ print('line', buf)
+
+ # scroll
+ fbuf.fill(0)
+ fbuf.pixel(2, 7, 1)
+ fbuf.scroll(0, 1)
+ print(buf)
+ fbuf.scroll(0, -2)
+ print(buf)
+ fbuf.scroll(1, 0)
+ print(buf)
+ fbuf.scroll(-1, 0)
+ print(buf)
+ fbuf.scroll(2, 2)
+ print(buf)
+
+ # print text
+ fbuf.fill(0)
+ fbuf.text("hello", 0, 0, 1)
+ print(buf)
+ fbuf.text("hello", 0, 0, 0) # clear
+ print(buf)
+
+ # char out of font range set to chr(127)
+ fbuf.text(str(chr(31)), 0, 0)
+ print(buf)
+ print()
+
+# test invalid constructor, and stride argument
try:
- fbuf = framebuf.FrameBuffer(buf, w, h, 2, framebuf.MVLSB)
+ fbuf = framebuf.FrameBuffer(buf, w, h, -1, w)
except ValueError:
- print("ValueError")
+ print("ValueError")
# test legacy constructor
fbuf = framebuf.FrameBuffer1(buf, w, h)
fbuf = framebuf.FrameBuffer1(buf, w, h, w)
+print(framebuf.MVLSB == framebuf.MONO_VLSB)
diff --git a/tests/extmod/framebuf1.py.exp b/tests/extmod/framebuf1.py.exp
index 83d775d3c..d954623de 100644
--- a/tests/extmod/framebuf1.py.exp
+++ b/tests/extmod/framebuf1.py.exp
@@ -1,3 +1,4 @@
+MONO_VLSB
0
bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff')
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
@@ -18,4 +19,50 @@ bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
bytearray(b'\x00\x7f\x7f\x04\x04\x00\x00\x00\x00\x00')
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
bytearray(b'\xaaU\xaaU\xaa\x00\x00\x00\x00\x00')
+
+MONO_HLSB
+0
+bytearray(b'\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+1 0
+hline bytearray(b'\x00\xf8\x00\x00\x00\x00\x00\x00\x00\x00')
+vline bytearray(b'@@@@@@@@@@')
+rect bytearray(b'\x00pPp\x00\x00\x00\x00\x00\x00')
+fill_rect bytearray(b'\x00ppp\x00\x00\x00\x00\x00\x00')
+line bytearray(b'\x00@ \x10\x00\x00\x00\x00\x00\x00')
+line bytearray(b'\x00 \x10\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00 \x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00 \x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00 \x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00')
+bytearray(b'``x````\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'P\xa8P\xa8P\xa8P\xa8\x00\x00')
+
+MONO_HMSB
+0
+bytearray(b'\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f\x1f')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+1 0
+hline bytearray(b'\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00')
+vline bytearray(b'\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02')
+rect bytearray(b'\x00\x0e\n\x0e\x00\x00\x00\x00\x00\x00')
+fill_rect bytearray(b'\x00\x0e\x0e\x0e\x00\x00\x00\x00\x00\x00')
+line bytearray(b'\x00\x02\x04\x08\x00\x00\x00\x00\x00\x00')
+line bytearray(b'\x00\x04\x04\x08\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00')
+bytearray(b'\x06\x06\x1e\x06\x06\x06\x06\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\n\x15\n\x15\n\x15\n\x15\x00\x00')
+
ValueError
+True
diff --git a/tests/extmod/framebuf4.py b/tests/extmod/framebuf4.py
new file mode 100644
index 000000000..641f5bfc5
--- /dev/null
+++ b/tests/extmod/framebuf4.py
@@ -0,0 +1,54 @@
+try:
+ import framebuf
+except ImportError:
+ print("SKIP")
+ import sys
+ sys.exit()
+
+def printbuf():
+ print("--8<--")
+ for y in range(h):
+ print(buf[y * w // 2:(y + 1) * w // 2])
+ print("-->8--")
+
+w = 16
+h = 8
+buf = bytearray(w * h // 2)
+fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS4_HMSB)
+
+# fill
+fbuf.fill(0x0f)
+printbuf()
+fbuf.fill(0xa0)
+printbuf()
+
+# put pixel
+fbuf.pixel(0, 0, 0x01)
+printbuf()
+fbuf.pixel(w-1, 0, 0x02)
+printbuf()
+fbuf.pixel(w-1, h-1, 0x03)
+printbuf()
+fbuf.pixel(0, h-1, 0x04)
+printbuf()
+
+# get pixel
+print(fbuf.pixel(0, 0), fbuf.pixel(w-1, 0), fbuf.pixel(w-1, h-1), fbuf.pixel(0, h-1))
+print(fbuf.pixel(1, 0), fbuf.pixel(w-2, 0), fbuf.pixel(w-2, h-1), fbuf.pixel(1, h-1))
+
+# fill rect
+fbuf.fill_rect(0, 0, w, h, 0x0f)
+printbuf()
+fbuf.fill_rect(0, 0, w, h, 0xf0)
+fbuf.fill_rect(1, 0, w//2+1, 1, 0xf1)
+printbuf()
+fbuf.fill_rect(1, 0, w//2+1, 1, 0x10)
+fbuf.fill_rect(1, 0, w//2, 1, 0xf1)
+printbuf()
+fbuf.fill_rect(1, 0, w//2, 1, 0x10)
+fbuf.fill_rect(0, h-4, w//2+1, 4, 0xaf)
+printbuf()
+fbuf.fill_rect(0, h-4, w//2+1, 4, 0xb0)
+fbuf.fill_rect(0, h-4, w//2, 4, 0xaf)
+printbuf()
+fbuf.fill_rect(0, h-4, w//2, 4, 0xb0)
diff --git a/tests/extmod/framebuf4.py.exp b/tests/extmod/framebuf4.py.exp
new file mode 100644
index 000000000..0865470a0
--- /dev/null
+++ b/tests/extmod/framebuf4.py.exp
@@ -0,0 +1,112 @@
+--8<--
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+-->8--
+--8<--
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+-->8--
+--8<--
+bytearray(b'\x10\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+-->8--
+--8<--
+bytearray(b'\x10\x00\x00\x00\x00\x00\x00\x02')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+-->8--
+--8<--
+bytearray(b'\x10\x00\x00\x00\x00\x00\x00\x02')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x03')
+-->8--
+--8<--
+bytearray(b'\x10\x00\x00\x00\x00\x00\x00\x02')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'@\x00\x00\x00\x00\x00\x00\x03')
+-->8--
+1 2 3 4
+0 0 0 0
+--8<--
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff')
+-->8--
+--8<--
+bytearray(b'\x01\x11\x11\x11\x11\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+-->8--
+--8<--
+bytearray(b'\x01\x11\x11\x11\x10\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+-->8--
+--8<--
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\xff\xff\xff\xff\xf0\x00\x00\x00')
+bytearray(b'\xff\xff\xff\xff\xf0\x00\x00\x00')
+bytearray(b'\xff\xff\xff\xff\xf0\x00\x00\x00')
+bytearray(b'\xff\xff\xff\xff\xf0\x00\x00\x00')
+-->8--
+--8<--
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
+bytearray(b'\xff\xff\xff\xff\x00\x00\x00\x00')
+bytearray(b'\xff\xff\xff\xff\x00\x00\x00\x00')
+bytearray(b'\xff\xff\xff\xff\x00\x00\x00\x00')
+bytearray(b'\xff\xff\xff\xff\x00\x00\x00\x00')
+-->8--
diff --git a/tests/extmod/machine1.py b/tests/extmod/machine1.py
index 433a18037..e0c561168 100644
--- a/tests/extmod/machine1.py
+++ b/tests/extmod/machine1.py
@@ -5,7 +5,8 @@ try:
import umachine as machine
except ImportError:
import machine
-except ImportError:
+ machine.mem8
+except:
print("SKIP")
import sys
sys.exit()
diff --git a/tests/extmod/machine_pulse.py b/tests/extmod/machine_pulse.py
index b6e126435..6491b5409 100644
--- a/tests/extmod/machine_pulse.py
+++ b/tests/extmod/machine_pulse.py
@@ -43,12 +43,5 @@ t = machine.time_pulse_us(p, 0)
print(type(t))
p = ConstPin(0)
-try:
- machine.time_pulse_us(p, 1, 10)
-except OSError:
- print("OSError")
-
-try:
- machine.time_pulse_us(p, 0, 10)
-except OSError:
- print("OSError")
+print(machine.time_pulse_us(p, 1, 10))
+print(machine.time_pulse_us(p, 0, 10))
diff --git a/tests/extmod/machine_pulse.py.exp b/tests/extmod/machine_pulse.py.exp
index f9a474218..20d4c1043 100644
--- a/tests/extmod/machine_pulse.py.exp
+++ b/tests/extmod/machine_pulse.py.exp
@@ -5,5 +5,5 @@ value: 1
value: 0
value: 1
<class 'int'>
-OSError
-OSError
+-2
+-1
diff --git a/tests/extmod/machine_signal.py b/tests/extmod/machine_signal.py
new file mode 100644
index 000000000..96b8f43c7
--- /dev/null
+++ b/tests/extmod/machine_signal.py
@@ -0,0 +1,40 @@
+# test machine.Signal class
+
+try:
+ import umachine as machine
+except ImportError:
+ import machine
+try:
+ machine.PinBase
+ machine.Signal
+except AttributeError:
+ print("SKIP")
+ import sys
+ sys.exit()
+
+class Pin(machine.PinBase):
+ def __init__(self):
+ self.v = 0
+
+ def value(self, v=None):
+ if v is None:
+ return self.v
+ else:
+ self.v = int(v)
+
+
+# test non-inverted
+p = Pin()
+s = machine.Signal(p)
+s.value(0)
+print(p.value(), s.value())
+s.value(1)
+print(p.value(), s.value())
+
+# test inverted, and using on/off methods
+p = Pin()
+s = machine.Signal(p, invert=True)
+s.off()
+print(p.value(), s.value())
+s.on()
+print(p.value(), s.value())
diff --git a/tests/extmod/machine_signal.py.exp b/tests/extmod/machine_signal.py.exp
new file mode 100644
index 000000000..7e9dd6796
--- /dev/null
+++ b/tests/extmod/machine_signal.py.exp
@@ -0,0 +1,4 @@
+0 0
+1 1
+1 0
+0 1
diff --git a/tests/extmod/ubinascii_a2b_base64.py b/tests/extmod/ubinascii_a2b_base64.py
index 97c451950..58eb0b50b 100644
--- a/tests/extmod/ubinascii_a2b_base64.py
+++ b/tests/extmod/ubinascii_a2b_base64.py
@@ -1,7 +1,12 @@
try:
- import ubinascii as binascii
+ try:
+ import ubinascii as binascii
+ except ImportError:
+ import binascii
except ImportError:
- import binascii
+ import sys
+ print("SKIP")
+ sys.exit()
print(binascii.a2b_base64(b''))
print(binascii.a2b_base64(b'Zg=='))
diff --git a/tests/extmod/ubinascii_b2a_base64.py b/tests/extmod/ubinascii_b2a_base64.py
index fdcaf32dd..1c0c30311 100644
--- a/tests/extmod/ubinascii_b2a_base64.py
+++ b/tests/extmod/ubinascii_b2a_base64.py
@@ -1,7 +1,12 @@
try:
- import ubinascii as binascii
+ try:
+ import ubinascii as binascii
+ except ImportError:
+ import binascii
except ImportError:
- import binascii
+ import sys
+ print("SKIP")
+ sys.exit()
print(binascii.b2a_base64(b''))
print(binascii.b2a_base64(b'f'))
diff --git a/tests/extmod/ubinascii_crc32.py b/tests/extmod/ubinascii_crc32.py
index 2c4017751..b82c44d6b 100644
--- a/tests/extmod/ubinascii_crc32.py
+++ b/tests/extmod/ubinascii_crc32.py
@@ -1,7 +1,13 @@
try:
- import ubinascii as binascii
+ try:
+ import ubinascii as binascii
+ except ImportError:
+ import binascii
except ImportError:
- import binascii
+ import sys
+ print("SKIP")
+ sys.exit()
+
try:
binascii.crc32
except AttributeError:
diff --git a/tests/extmod/ubinascii_hexlify.py b/tests/extmod/ubinascii_hexlify.py
index 14c37cb4b..5d70bda96 100644
--- a/tests/extmod/ubinascii_hexlify.py
+++ b/tests/extmod/ubinascii_hexlify.py
@@ -1,7 +1,12 @@
try:
- import ubinascii as binascii
+ try:
+ import ubinascii as binascii
+ except ImportError:
+ import binascii
except ImportError:
- import binascii
+ import sys
+ print("SKIP")
+ sys.exit()
print(binascii.hexlify(b'\x00\x01\x02\x03\x04\x05\x06\x07'))
print(binascii.hexlify(b'\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'))
diff --git a/tests/extmod/ubinascii_micropython.py b/tests/extmod/ubinascii_micropython.py
index d68da3205..96f566bd1 100644
--- a/tests/extmod/ubinascii_micropython.py
+++ b/tests/extmod/ubinascii_micropython.py
@@ -1,7 +1,12 @@
try:
- import ubinascii as binascii
+ try:
+ import ubinascii as binascii
+ except ImportError:
+ import binascii
except ImportError:
- import binascii
+ import sys
+ print("SKIP")
+ sys.exit()
# two arguments supported in uPy but not CPython
a = binascii.hexlify(b'123', ':')
diff --git a/tests/extmod/ubinascii_unhexlify.py b/tests/extmod/ubinascii_unhexlify.py
index 99c2c0208..e669789ba 100644
--- a/tests/extmod/ubinascii_unhexlify.py
+++ b/tests/extmod/ubinascii_unhexlify.py
@@ -1,7 +1,12 @@
try:
- import ubinascii as binascii
+ try:
+ import ubinascii as binascii
+ except ImportError:
+ import binascii
except ImportError:
- import binascii
+ import sys
+ print("SKIP")
+ sys.exit()
print(binascii.unhexlify(b'0001020304050607'))
print(binascii.unhexlify(b'08090a0b0c0d0e0f'))
diff --git a/tests/extmod/uctypes_32bit_intbig.py b/tests/extmod/uctypes_32bit_intbig.py
new file mode 100644
index 000000000..a082dc370
--- /dev/null
+++ b/tests/extmod/uctypes_32bit_intbig.py
@@ -0,0 +1,54 @@
+# This test checks previously known problem values for 32-bit ports.
+# It's less useful for 64-bit ports.
+try:
+ import uctypes
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+buf = b"12345678abcd"
+struct = uctypes.struct(
+ uctypes.addressof(buf),
+ {"f32": uctypes.UINT32 | 0, "f64": uctypes.UINT64 | 4},
+ uctypes.LITTLE_ENDIAN
+)
+
+struct.f32 = 0x7fffffff
+print(buf)
+
+struct.f32 = 0x80000000
+print(buf)
+
+struct.f32 = 0xff010203
+print(buf)
+
+struct.f64 = 0x80000000
+print(buf)
+
+struct.f64 = 0x80000000 * 2
+print(buf)
+
+print("=")
+
+buf = b"12345678abcd"
+struct = uctypes.struct(
+ uctypes.addressof(buf),
+ {"f32": uctypes.UINT32 | 0, "f64": uctypes.UINT64 | 4},
+ uctypes.BIG_ENDIAN
+)
+
+struct.f32 = 0x7fffffff
+print(buf)
+
+struct.f32 = 0x80000000
+print(buf)
+
+struct.f32 = 0xff010203
+print(buf)
+
+struct.f64 = 0x80000000
+print(buf)
+
+struct.f64 = 0x80000000 * 2
+print(buf)
diff --git a/tests/extmod/uctypes_32bit_intbig.py.exp b/tests/extmod/uctypes_32bit_intbig.py.exp
new file mode 100644
index 000000000..d1fc1fe35
--- /dev/null
+++ b/tests/extmod/uctypes_32bit_intbig.py.exp
@@ -0,0 +1,11 @@
+b'\xff\xff\xff\x7f5678abcd'
+b'\x00\x00\x00\x805678abcd'
+b'\x03\x02\x01\xff5678abcd'
+b'\x03\x02\x01\xff\x00\x00\x00\x80\x00\x00\x00\x00'
+b'\x03\x02\x01\xff\x00\x00\x00\x00\x01\x00\x00\x00'
+=
+b'\x7f\xff\xff\xff5678abcd'
+b'\x80\x00\x00\x005678abcd'
+b'\xff\x01\x02\x035678abcd'
+b'\xff\x01\x02\x03\x00\x00\x00\x00\x80\x00\x00\x00'
+b'\xff\x01\x02\x03\x00\x00\x00\x01\x00\x00\x00\x00'
diff --git a/tests/extmod/uctypes_array_assign_le.py b/tests/extmod/uctypes_array_assign_le.py
index 18d63f8bf..bae467d09 100644
--- a/tests/extmod/uctypes_array_assign_le.py
+++ b/tests/extmod/uctypes_array_assign_le.py
@@ -1,4 +1,9 @@
-import uctypes
+try:
+ import uctypes
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
desc = {
# arr is array at offset 0, of UINT8 elements, array size is 2
diff --git a/tests/extmod/uctypes_array_assign_native_le.py b/tests/extmod/uctypes_array_assign_native_le.py
index 632c4d252..f0ecc0dad 100644
--- a/tests/extmod/uctypes_array_assign_native_le.py
+++ b/tests/extmod/uctypes_array_assign_native_le.py
@@ -1,5 +1,9 @@
import sys
-import uctypes
+try:
+ import uctypes
+except ImportError:
+ print("SKIP")
+ sys.exit()
if sys.byteorder != "little":
print("SKIP")
@@ -66,16 +70,6 @@ S.arr10[0] = 0x11223344
print(hex(S.arr10[0]))
assert hex(S.arr10[0]) == "0x11223344"
-# assign int64
-S.arr11[0] = 0x11223344
-print(hex(S.arr11[0]))
-assert hex(S.arr11[0]) == "0x11223344"
-
-# assign uint64
-S.arr12[0] = 0x11223344
-print(hex(S.arr12[0]))
-assert hex(S.arr12[0]) == "0x11223344"
-
# index out of range
try:
print(S.arr8[2])
diff --git a/tests/extmod/uctypes_array_assign_native_le.py.exp b/tests/extmod/uctypes_array_assign_native_le.py.exp
index 4efcdec66..9d67b1c77 100644
--- a/tests/extmod/uctypes_array_assign_native_le.py.exp
+++ b/tests/extmod/uctypes_array_assign_native_le.py.exp
@@ -6,8 +6,6 @@ True
0x11
0x1122
0x11223344
-0x11223344
-0x11223344
IndexError
TypeError
TypeError
diff --git a/tests/extmod/uctypes_array_assign_native_le_intbig.py b/tests/extmod/uctypes_array_assign_native_le_intbig.py
new file mode 100644
index 000000000..f29a3b66e
--- /dev/null
+++ b/tests/extmod/uctypes_array_assign_native_le_intbig.py
@@ -0,0 +1,43 @@
+import sys
+try:
+ import uctypes
+except ImportError:
+ print("SKIP")
+ sys.exit()
+
+if sys.byteorder != "little":
+ print("SKIP")
+ sys.exit()
+
+desc = {
+ # arr is array at offset 0, of UINT8 elements, array size is 2
+ "arr": (uctypes.ARRAY | 0, uctypes.UINT8 | 2),
+ # arr2 is array at offset 0, size 2, of structures defined recursively
+ "arr2": (uctypes.ARRAY | 0, 2, {"b": uctypes.UINT8 | 0}),
+ "arr3": (uctypes.ARRAY | 2, uctypes.UINT16 | 2),
+
+ # aligned
+ "arr5": (uctypes.ARRAY | 0, uctypes.UINT32 | 1),
+ "arr7": (uctypes.ARRAY | 0, 1, {"l": uctypes.UINT32 | 0}),
+
+ "arr8": (uctypes.ARRAY | 0, uctypes.INT8 | 1),
+ "arr9": (uctypes.ARRAY | 0, uctypes.INT16 | 1),
+ "arr10": (uctypes.ARRAY | 0, uctypes.INT32 | 1),
+ "arr11": (uctypes.ARRAY | 0, uctypes.INT64 | 1),
+ "arr12": (uctypes.ARRAY | 0, uctypes.UINT64| 1),
+ "arr13": (uctypes.ARRAY | 1, 1, {"l": {}}),
+}
+
+data = bytearray(8)
+
+S = uctypes.struct(uctypes.addressof(data), desc)
+
+# assign int64
+S.arr11[0] = 0x11223344
+print(hex(S.arr11[0]))
+assert hex(S.arr11[0]) == "0x11223344"
+
+# assign uint64
+S.arr12[0] = 0x11223344
+print(hex(S.arr12[0]))
+assert hex(S.arr12[0]) == "0x11223344"
diff --git a/tests/extmod/uctypes_array_assign_native_le_intbig.py.exp b/tests/extmod/uctypes_array_assign_native_le_intbig.py.exp
new file mode 100644
index 000000000..0394e9ae1
--- /dev/null
+++ b/tests/extmod/uctypes_array_assign_native_le_intbig.py.exp
@@ -0,0 +1,2 @@
+0x11223344
+0x11223344
diff --git a/tests/extmod/uctypes_bytearray.py b/tests/extmod/uctypes_bytearray.py
index 7294b7ea4..bf7845ab2 100644
--- a/tests/extmod/uctypes_bytearray.py
+++ b/tests/extmod/uctypes_bytearray.py
@@ -1,4 +1,9 @@
-import uctypes
+try:
+ import uctypes
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
desc = {
"arr": (uctypes.ARRAY | 0, uctypes.UINT8 | 2),
diff --git a/tests/extmod/uctypes_le.py b/tests/extmod/uctypes_le.py
index 5ae410b01..829beda58 100644
--- a/tests/extmod/uctypes_le.py
+++ b/tests/extmod/uctypes_le.py
@@ -1,4 +1,9 @@
-import uctypes
+try:
+ import uctypes
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
desc = {
"s0": uctypes.UINT16 | 0,
diff --git a/tests/extmod/uctypes_le_float.py b/tests/extmod/uctypes_le_float.py
index c85b75f36..a61305ba8 100644
--- a/tests/extmod/uctypes_le_float.py
+++ b/tests/extmod/uctypes_le_float.py
@@ -1,4 +1,9 @@
-import uctypes
+try:
+ import uctypes
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
desc = {
"f32": uctypes.FLOAT32 | 0,
diff --git a/tests/extmod/uctypes_native_float.py b/tests/extmod/uctypes_native_float.py
index 89aac8bf3..80cb54383 100644
--- a/tests/extmod/uctypes_native_float.py
+++ b/tests/extmod/uctypes_native_float.py
@@ -1,4 +1,9 @@
-import uctypes
+try:
+ import uctypes
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
desc = {
"f32": uctypes.FLOAT32 | 0,
diff --git a/tests/extmod/uctypes_native_le.py b/tests/extmod/uctypes_native_le.py
index ef0f9f5e9..5900224d4 100644
--- a/tests/extmod/uctypes_native_le.py
+++ b/tests/extmod/uctypes_native_le.py
@@ -2,7 +2,11 @@
# Codepaths for packed vs native structures are different. This test only works
# on little-endian machine (no matter if 32 or 64 bit).
import sys
-import uctypes
+try:
+ import uctypes
+except ImportError:
+ print("SKIP")
+ sys.exit()
if sys.byteorder != "little":
print("SKIP")
diff --git a/tests/extmod/uctypes_print.py b/tests/extmod/uctypes_print.py
index 71981ce7e..76a009dc7 100644
--- a/tests/extmod/uctypes_print.py
+++ b/tests/extmod/uctypes_print.py
@@ -1,6 +1,10 @@
# test printing of uctypes objects
-
-import uctypes
+try:
+ import uctypes
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
# we use an address of "0" because we just want to print something deterministic
# and don't actually need to set/get any values in the struct
diff --git a/tests/extmod/uctypes_ptr_le.py b/tests/extmod/uctypes_ptr_le.py
index d0216dfb8..e8a6243ce 100644
--- a/tests/extmod/uctypes_ptr_le.py
+++ b/tests/extmod/uctypes_ptr_le.py
@@ -1,5 +1,9 @@
import sys
-import uctypes
+try:
+ import uctypes
+except ImportError:
+ print("SKIP")
+ sys.exit()
if sys.byteorder != "little":
print("SKIP")
diff --git a/tests/extmod/uctypes_ptr_native_le.py b/tests/extmod/uctypes_ptr_native_le.py
index 6f011c3c2..9b016c04d 100644
--- a/tests/extmod/uctypes_ptr_native_le.py
+++ b/tests/extmod/uctypes_ptr_native_le.py
@@ -1,5 +1,9 @@
import sys
-import uctypes
+try:
+ import uctypes
+except ImportError:
+ print("SKIP")
+ sys.exit()
if sys.byteorder != "little":
print("SKIP")
diff --git a/tests/extmod/uctypes_sizeof.py b/tests/extmod/uctypes_sizeof.py
index fcfd8ecd7..266cd0694 100644
--- a/tests/extmod/uctypes_sizeof.py
+++ b/tests/extmod/uctypes_sizeof.py
@@ -1,4 +1,9 @@
-import uctypes
+try:
+ import uctypes
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
desc = {
# arr is array at offset 0, of UINT8 elements, array size is 2
diff --git a/tests/extmod/uctypes_sizeof_native.py b/tests/extmod/uctypes_sizeof_native.py
index f830a1f85..f676c8c6d 100644
--- a/tests/extmod/uctypes_sizeof_native.py
+++ b/tests/extmod/uctypes_sizeof_native.py
@@ -1,4 +1,9 @@
-import uctypes
+try:
+ import uctypes
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
S1 = {}
assert uctypes.sizeof(S1) == 0
diff --git a/tests/extmod/uheapq1.py b/tests/extmod/uheapq1.py
index e71f817ef..4b0e5de57 100644
--- a/tests/extmod/uheapq1.py
+++ b/tests/extmod/uheapq1.py
@@ -1,7 +1,12 @@
try:
import uheapq as heapq
except:
- import heapq
+ try:
+ import heapq
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
try:
heapq.heappop([])
diff --git a/tests/extmod/ujson_dumps.py b/tests/extmod/ujson_dumps.py
index c0ee60d73..4a02f5170 100644
--- a/tests/extmod/ujson_dumps.py
+++ b/tests/extmod/ujson_dumps.py
@@ -1,7 +1,12 @@
try:
import ujson as json
except ImportError:
- import json
+ try:
+ import json
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
print(json.dumps(False))
print(json.dumps(True))
diff --git a/tests/extmod/ujson_dumps_extra.py b/tests/extmod/ujson_dumps_extra.py
index 0e593c3e9..a52e8224c 100644
--- a/tests/extmod/ujson_dumps_extra.py
+++ b/tests/extmod/ujson_dumps_extra.py
@@ -1,5 +1,10 @@
# test uPy ujson behaviour that's not valid in CPy
-import ujson
+try:
+ import ujson
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
print(ujson.dumps(b'1234'))
diff --git a/tests/extmod/ujson_dumps_float.py b/tests/extmod/ujson_dumps_float.py
index f6ba5f113..d949ea6dd 100644
--- a/tests/extmod/ujson_dumps_float.py
+++ b/tests/extmod/ujson_dumps_float.py
@@ -1,6 +1,11 @@
try:
import ujson as json
except ImportError:
- import json
+ try:
+ import json
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
print(json.dumps(1.2))
diff --git a/tests/extmod/ujson_load.py b/tests/extmod/ujson_load.py
index bf484a207..901132a5f 100644
--- a/tests/extmod/ujson_load.py
+++ b/tests/extmod/ujson_load.py
@@ -2,8 +2,13 @@ try:
from uio import StringIO
import ujson as json
except:
- from io import StringIO
- import json
+ try:
+ from io import StringIO
+ import json
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
print(json.load(StringIO('null')))
print(json.load(StringIO('"abc\\u0064e"')))
diff --git a/tests/extmod/ujson_loads.py b/tests/extmod/ujson_loads.py
index 37576e6ae..b2e18e3af 100644
--- a/tests/extmod/ujson_loads.py
+++ b/tests/extmod/ujson_loads.py
@@ -1,7 +1,12 @@
try:
import ujson as json
-except:
- import json
+except ImportError:
+ try:
+ import json
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
def my_print(o):
if isinstance(o, dict):
diff --git a/tests/extmod/ujson_loads_float.py b/tests/extmod/ujson_loads_float.py
index f5e754608..b20a412ff 100644
--- a/tests/extmod/ujson_loads_float.py
+++ b/tests/extmod/ujson_loads_float.py
@@ -1,7 +1,12 @@
try:
import ujson as json
-except:
- import json
+except ImportError:
+ try:
+ import json
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
def my_print(o):
print('%.3f' % o)
diff --git a/tests/extmod/urandom_basic.py b/tests/extmod/urandom_basic.py
index bf00035bd..885b8517f 100644
--- a/tests/extmod/urandom_basic.py
+++ b/tests/extmod/urandom_basic.py
@@ -1,7 +1,12 @@
try:
import urandom as random
except ImportError:
- import random
+ try:
+ import random
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
# check getrandbits returns a value within the bit range
for b in (1, 2, 3, 4, 16, 32):
diff --git a/tests/extmod/urandom_extra.py b/tests/extmod/urandom_extra.py
index 004fb10cc..925dd0dbc 100644
--- a/tests/extmod/urandom_extra.py
+++ b/tests/extmod/urandom_extra.py
@@ -1,7 +1,12 @@
try:
import urandom as random
except ImportError:
- import random
+ try:
+ import random
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
try:
random.randint
diff --git a/tests/extmod/ure1.py b/tests/extmod/ure1.py
index aeadf4e5c..a867f1751 100644
--- a/tests/extmod/ure1.py
+++ b/tests/extmod/ure1.py
@@ -1,7 +1,12 @@
try:
import ure as re
except ImportError:
- import re
+ try:
+ import re
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
r = re.compile(".+")
m = r.match("abc")
@@ -11,6 +16,10 @@ try:
except IndexError:
print("IndexError")
+# conversion of re and match to string
+str(r)
+str(m)
+
r = re.compile("(.+)1")
m = r.match("xyz781")
print(m.group(0))
@@ -63,6 +72,11 @@ m = re.match('^ab$', 'ab'); print(m.group(0))
m = re.match('a|b', 'b'); print(m.group(0))
m = re.match('a|b|c', 'c'); print(m.group(0))
+# Case where anchors fail to match
+r = re.compile("^b|b$")
+m = r.search("abc")
+print(m)
+
try:
re.compile("*")
except:
diff --git a/tests/extmod/ure_debug.py b/tests/extmod/ure_debug.py
new file mode 100644
index 000000000..252df21e3
--- /dev/null
+++ b/tests/extmod/ure_debug.py
@@ -0,0 +1,9 @@
+# test printing debugging info when compiling
+try:
+ import ure
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+ure.compile('^a|b[0-9]\w$', ure.DEBUG)
diff --git a/tests/extmod/ure_debug.py.exp b/tests/extmod/ure_debug.py.exp
new file mode 100644
index 000000000..45f5e20f6
--- /dev/null
+++ b/tests/extmod/ure_debug.py.exp
@@ -0,0 +1,15 @@
+ 0: rsplit 5 (3)
+ 2: any
+ 3: jmp 0 (-5)
+ 5: save 0
+ 7: split 14 (5)
+ 9: assert bol
+10: char a
+12: jmp 23 (9)
+14: char b
+16: class 1 0x30-0x39
+20: namedclass w
+22: assert eol
+23: save 1
+25: match
+Bytes: 26, insts: 14
diff --git a/tests/extmod/ure_error.py b/tests/extmod/ure_error.py
index 1e9f66a9e..3f16f9158 100644
--- a/tests/extmod/ure_error.py
+++ b/tests/extmod/ure_error.py
@@ -2,8 +2,13 @@
try:
import ure as re
-except:
- import re
+except ImportError:
+ try:
+ import re
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
def test_re(r):
try:
diff --git a/tests/extmod/ure_group.py b/tests/extmod/ure_group.py
index 8078a0a85..98aae2a73 100644
--- a/tests/extmod/ure_group.py
+++ b/tests/extmod/ure_group.py
@@ -2,8 +2,13 @@
try:
import ure as re
-except:
- import re
+except ImportError:
+ try:
+ import re
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
def print_groups(match):
print('----')
diff --git a/tests/extmod/ure_namedclass.py b/tests/extmod/ure_namedclass.py
index 25f425ce7..e233f17c8 100644
--- a/tests/extmod/ure_namedclass.py
+++ b/tests/extmod/ure_namedclass.py
@@ -2,8 +2,13 @@
try:
import ure as re
-except:
- import re
+except ImportError:
+ try:
+ import re
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
def print_groups(match):
print('----')
diff --git a/tests/extmod/ure_split.py b/tests/extmod/ure_split.py
index 620fd9052..1e411c27c 100644
--- a/tests/extmod/ure_split.py
+++ b/tests/extmod/ure_split.py
@@ -1,7 +1,12 @@
try:
import ure as re
except ImportError:
- import re
+ try:
+ import re
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
r = re.compile(" ")
s = r.split("a b c foobar")
diff --git a/tests/extmod/ure_split_empty.py b/tests/extmod/ure_split_empty.py
index 6f31e6dc6..ad6334eba 100644
--- a/tests/extmod/ure_split_empty.py
+++ b/tests/extmod/ure_split_empty.py
@@ -4,7 +4,12 @@
# behaviour will change in a future version. MicroPython just stops
# splitting as soon as an empty match is found.
-import ure as re
+try:
+ import ure as re
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
r = re.compile(" *")
s = r.split("a b c foobar")
diff --git a/tests/extmod/ure_split_notimpl.py b/tests/extmod/ure_split_notimpl.py
new file mode 100644
index 000000000..eca3ea512
--- /dev/null
+++ b/tests/extmod/ure_split_notimpl.py
@@ -0,0 +1,12 @@
+try:
+ import ure as re
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+r = re.compile('( )')
+try:
+ s = r.split("a b c foobar")
+except NotImplementedError:
+ print('NotImplementedError')
diff --git a/tests/extmod/ure_split_notimpl.py.exp b/tests/extmod/ure_split_notimpl.py.exp
new file mode 100644
index 000000000..437f61670
--- /dev/null
+++ b/tests/extmod/ure_split_notimpl.py.exp
@@ -0,0 +1 @@
+NotImplementedError
diff --git a/tests/extmod/ussl_basic.py b/tests/extmod/ussl_basic.py
new file mode 100644
index 000000000..e9d435bca
--- /dev/null
+++ b/tests/extmod/ussl_basic.py
@@ -0,0 +1,52 @@
+# very basic test of ssl module, just to test the methods exist
+
+try:
+ import uio as io
+ import ussl as ssl
+except ImportError:
+ print("SKIP")
+ import sys
+ sys.exit()
+
+# create in client mode
+try:
+ ss = ssl.wrap_socket(io.BytesIO())
+except OSError as er:
+ print('wrap_socket:', repr(er))
+
+# create in server mode (can use this object for further tests)
+socket = io.BytesIO()
+ss = ssl.wrap_socket(socket, server_side=1)
+
+# print
+print(repr(ss)[:12])
+
+# setblocking
+try:
+ ss.setblocking(False)
+except NotImplementedError:
+ print('setblocking: NotImplementedError')
+ss.setblocking(True)
+
+# write
+print(ss.write(b'aaaa'))
+
+# read (underlying socket has no data)
+print(ss.read(8))
+
+# read (underlying socket has data, but it's bad data)
+socket.write(b'aaaaaaaaaaaaaaaa')
+socket.seek(0)
+try:
+ ss.read(8)
+except OSError as er:
+ print('read:', repr(er))
+
+# close
+ss.close()
+
+# write on closed socket
+try:
+ ss.write(b'aaaa')
+except OSError as er:
+ print('write:', repr(er))
diff --git a/tests/extmod/ussl_basic.py.exp b/tests/extmod/ussl_basic.py.exp
new file mode 100644
index 000000000..b4dd03860
--- /dev/null
+++ b/tests/extmod/ussl_basic.py.exp
@@ -0,0 +1,8 @@
+ssl_handshake_status: -256
+wrap_socket: OSError(5,)
+<_SSLSocket
+setblocking: NotImplementedError
+4
+b''
+read: OSError(-261,)
+write: OSError(-256,)
diff --git a/tests/extmod/utimeq1.py b/tests/extmod/utimeq1.py
index 9af723674..68d69e25e 100644
--- a/tests/extmod/utimeq1.py
+++ b/tests/extmod/utimeq1.py
@@ -34,6 +34,41 @@ try:
except IndexError:
pass
+# unsupported unary op
+try:
+ ~h
+ assert False
+except TypeError:
+ pass
+
+# pushing on full queue
+h = utimeq(1)
+h.push(1, 0, 0)
+try:
+ h.push(2, 0, 0)
+ assert False
+except IndexError:
+ pass
+
+# popping into invalid type
+try:
+ h.pop([])
+ assert False
+except TypeError:
+ pass
+
+# length
+assert len(h) == 1
+
+# peektime
+assert h.peektime() == 1
+
+# peektime with empty queue
+try:
+ utimeq(1).peektime()
+ assert False
+except IndexError:
+ pass
def pop_all(h):
l = []
diff --git a/tests/extmod/uzlib_decompio.py b/tests/extmod/uzlib_decompio.py
index 75a6df0ca..6f07c048c 100644
--- a/tests/extmod/uzlib_decompio.py
+++ b/tests/extmod/uzlib_decompio.py
@@ -1,8 +1,10 @@
try:
- import zlib
-except ImportError:
import uzlib as zlib
-import uio as io
+ import uio as io
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
# Raw DEFLATE bitstream
diff --git a/tests/extmod/uzlib_decompio_gz.py b/tests/extmod/uzlib_decompio_gz.py
index c7aac04e8..7572e9693 100644
--- a/tests/extmod/uzlib_decompio_gz.py
+++ b/tests/extmod/uzlib_decompio_gz.py
@@ -1,8 +1,10 @@
try:
- import zlib
-except ImportError:
import uzlib as zlib
-import uio as io
+ import uio as io
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
# gzip bitstream
@@ -18,6 +20,16 @@ print(inp.read(1))
print(inp.read())
print(buf.seek(0, 1))
+# Check FHCRC field
+buf = io.BytesIO(b'\x1f\x8b\x08\x02\x99\x0c\xe5W\x00\x03\x00\x00\xcbH\xcd\xc9\xc9\x07\x00\x86\xa6\x106\x05\x00\x00\x00')
+inp = zlib.DecompIO(buf, 16 + 8)
+print(inp.read())
+
+# Check FEXTRA field
+buf = io.BytesIO(b'\x1f\x8b\x08\x04\x99\x0c\xe5W\x00\x03\x01\x00X\xcbH\xcd\xc9\xc9\x07\x00\x86\xa6\x106\x05\x00\x00\x00')
+inp = zlib.DecompIO(buf, 16 + 8)
+print(inp.read())
+
# broken header
buf = io.BytesIO(b'\x1f\x8c\x08\x08\x99\x0c\xe5W\x00\x03hello\x00\xcbH\xcd\xc9\xc9\x07\x00\x86\xa6\x106\x05\x00\x00\x00')
try:
diff --git a/tests/extmod/uzlib_decompio_gz.py.exp b/tests/extmod/uzlib_decompio_gz.py.exp
index 2330580f8..20a30c82a 100644
--- a/tests/extmod/uzlib_decompio_gz.py.exp
+++ b/tests/extmod/uzlib_decompio_gz.py.exp
@@ -7,5 +7,7 @@ b'lo'
b''
b''
31
+b'hello'
+b'hello'
ValueError
OSError(22,)
diff --git a/tests/extmod/uzlib_decompress.py b/tests/extmod/uzlib_decompress.py
index 6892808cb..10121ee7e 100644
--- a/tests/extmod/uzlib_decompress.py
+++ b/tests/extmod/uzlib_decompress.py
@@ -1,7 +1,12 @@
try:
import zlib
except ImportError:
- import uzlib as zlib
+ try:
+ import uzlib as zlib
+ except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
PATTERNS = [
# Packed results produced by CPy's zlib.compress()
diff --git a/tests/extmod/vfs_basic.py b/tests/extmod/vfs_basic.py
new file mode 100644
index 000000000..a3b2f3c29
--- /dev/null
+++ b/tests/extmod/vfs_basic.py
@@ -0,0 +1,147 @@
+# test VFS functionality without any particular filesystem type
+
+try:
+ try:
+ import uos_vfs as uos
+ open = uos.vfs_open
+ except ImportError:
+ import uos
+ uos.mount
+except (ImportError, AttributeError):
+ print("SKIP")
+ import sys
+ sys.exit()
+
+
+class Filesystem:
+ def __init__(self, id):
+ self.id = id
+ def mount(self, readonly, mkfs):
+ print(self.id, 'mount', readonly, mkfs)
+ def umount(self):
+ print(self.id, 'umount')
+ def ilistdir(self, dir):
+ print(self.id, 'ilistdir', dir)
+ return iter([('a%d' % self.id, 0, 0)])
+ def chdir(self, dir):
+ print(self.id, 'chdir', dir)
+ def getcwd(self):
+ print(self.id, 'getcwd')
+ return 'dir%d' % self.id
+ def mkdir(self, path):
+ print(self.id, 'mkdir', path)
+ def remove(self, path):
+ print(self.id, 'remove', path)
+ def rename(self, old_path, new_path):
+ print(self.id, 'rename', old_path, new_path)
+ def rmdir(self, path):
+ print(self.id, 'rmdir', path)
+ def stat(self, path):
+ print(self.id, 'stat', path)
+ return (self.id,)
+ def statvfs(self, path):
+ print(self.id, 'statvfs', path)
+ return (self.id,)
+ def open(self, file, mode):
+ print(self.id, 'open', file, mode)
+
+
+# first we umount any existing mount points the target may have
+try:
+ uos.umount('/')
+except OSError:
+ pass
+for path in uos.listdir('/'):
+ uos.umount('/' + path)
+
+# stat root dir
+print(uos.stat('/'))
+
+# getcwd when in root dir
+print(uos.getcwd())
+
+# basic mounting and listdir
+uos.mount(Filesystem(1), '/test_mnt')
+print(uos.listdir())
+
+# ilistdir
+i = uos.ilistdir()
+print(next(i))
+try:
+ next(i)
+except StopIteration:
+ print('StopIteration')
+try:
+ next(i)
+except StopIteration:
+ print('StopIteration')
+
+# referencing the mount point in different ways
+print(uos.listdir('test_mnt'))
+print(uos.listdir('/test_mnt'))
+
+# mounting another filesystem
+uos.mount(Filesystem(2), '/test_mnt2', readonly=True)
+print(uos.listdir())
+print(uos.listdir('/test_mnt2'))
+
+# mounting over an existing mount point
+try:
+ uos.mount(Filesystem(3), '/test_mnt2')
+except OSError:
+ print('OSError')
+
+# mkdir of a mount point
+try:
+ uos.mkdir('/test_mnt')
+except OSError:
+ print('OSError')
+
+# rename across a filesystem
+try:
+ uos.rename('/test_mnt/a', '/test_mnt2/b')
+except OSError:
+ print('OSError')
+
+# delegating to mounted filesystem
+uos.chdir('test_mnt')
+print(uos.listdir())
+print(uos.getcwd())
+uos.mkdir('test_dir')
+uos.remove('test_file')
+uos.rename('test_file', 'test_file2')
+uos.rmdir('test_dir')
+print(uos.stat('test_file'))
+print(uos.statvfs('/test_mnt'))
+open('test_file')
+open('test_file', 'wb')
+
+# umount
+uos.umount('/test_mnt')
+uos.umount('/test_mnt2')
+
+# umount a non-existent mount point
+try:
+ uos.umount('/test_mnt')
+except OSError:
+ print('OSError')
+
+# root dir
+uos.mount(Filesystem(3), '/')
+print(uos.listdir())
+open('test')
+
+uos.mount(Filesystem(4), '/mnt')
+print(uos.listdir())
+print(uos.listdir('/mnt'))
+uos.chdir('/mnt')
+print(uos.listdir())
+
+# chdir to a subdir within root-mounted vfs, and then listdir
+uos.chdir('/subdir')
+print(uos.listdir())
+uos.chdir('/')
+
+uos.umount('/')
+print(uos.listdir('/'))
+uos.umount('/mnt')
diff --git a/tests/extmod/vfs_basic.py.exp b/tests/extmod/vfs_basic.py.exp
new file mode 100644
index 000000000..8a23aa8ae
--- /dev/null
+++ b/tests/extmod/vfs_basic.py.exp
@@ -0,0 +1,56 @@
+(16384, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+/
+1 mount False False
+['test_mnt']
+('test_mnt', 16384, 0)
+StopIteration
+StopIteration
+1 ilistdir /
+['a1']
+1 ilistdir /
+['a1']
+2 mount True False
+['test_mnt', 'test_mnt2']
+2 ilistdir /
+['a2']
+3 mount False False
+OSError
+OSError
+OSError
+1 chdir /
+1 ilistdir
+['a1']
+1 getcwd
+/test_mntdir1
+1 mkdir test_dir
+1 remove test_file
+1 rename test_file test_file2
+1 rmdir test_dir
+1 stat test_file
+(1,)
+1 statvfs /
+(1,)
+1 open test_file r
+1 open test_file wb
+1 umount
+2 umount
+OSError
+3 mount False False
+3 ilistdir /
+['a3']
+3 open test r
+4 mount False False
+3 ilistdir /
+['mnt', 'a3']
+4 ilistdir /
+['a4']
+4 chdir /
+4 ilistdir
+['a4']
+3 chdir /subdir
+3 ilistdir
+['a3']
+3 chdir /
+3 umount
+['mnt']
+4 umount
diff --git a/tests/extmod/vfs_fat_fileio.py.exp b/tests/extmod/vfs_fat_fileio.py.exp
deleted file mode 100644
index a09442ae8..000000000
--- a/tests/extmod/vfs_fat_fileio.py.exp
+++ /dev/null
@@ -1,25 +0,0 @@
-<io.TextIOWrapper >
-True
-True
-True
-True
-hello!world!
-12
-h
-e
-True
-d
-hello!world!
-True
-True
-True
-True
-True
-b'data in file'
-True
-['sub_file.txt', 'file.txt']
-['foo_file.txt', 'foo_dir', 'moved-to-root.txt']
-['foo_file.txt', 'foo_dir', 'moved-to-root.txt']
-new text
-['moved-to-root.txt']
-ENOSPC: True
diff --git a/tests/extmod/vfs_fat_fileio1.py b/tests/extmod/vfs_fat_fileio1.py
new file mode 100644
index 000000000..9036df7a5
--- /dev/null
+++ b/tests/extmod/vfs_fat_fileio1.py
@@ -0,0 +1,118 @@
+import sys
+try:
+ import uerrno
+ try:
+ import uos_vfs as uos
+ open = uos.vfs_open
+ except ImportError:
+ import uos
+except ImportError:
+ print("SKIP")
+ sys.exit()
+
+try:
+ uos.VfsFat
+except AttributeError:
+ print("SKIP")
+ sys.exit()
+
+
+class RAMFS:
+
+ SEC_SIZE = 512
+
+ def __init__(self, blocks):
+ self.data = bytearray(blocks * self.SEC_SIZE)
+
+ def readblocks(self, n, buf):
+ #print("readblocks(%s, %x(%d))" % (n, id(buf), len(buf)))
+ for i in range(len(buf)):
+ buf[i] = self.data[n * self.SEC_SIZE + i]
+
+ def writeblocks(self, n, buf):
+ #print("writeblocks(%s, %x)" % (n, id(buf)))
+ for i in range(len(buf)):
+ self.data[n * self.SEC_SIZE + i] = buf[i]
+
+ def ioctl(self, op, arg):
+ #print("ioctl(%d, %r)" % (op, arg))
+ if op == 4: # BP_IOCTL_SEC_COUNT
+ return len(self.data) // self.SEC_SIZE
+ if op == 5: # BP_IOCTL_SEC_SIZE
+ return self.SEC_SIZE
+
+
+try:
+ bdev = RAMFS(50)
+except MemoryError:
+ print("SKIP")
+ sys.exit()
+
+uos.VfsFat.mkfs(bdev)
+vfs = uos.VfsFat(bdev)
+uos.mount(vfs, '/ramdisk')
+uos.chdir('/ramdisk')
+
+# file IO
+f = open("foo_file.txt", "w")
+print(str(f)[:17], str(f)[-1:])
+f.write("hello!")
+f.flush()
+f.close()
+f.close() # allowed
+try:
+ f.write("world!")
+except OSError as e:
+ print(e.args[0] == uerrno.EINVAL)
+
+try:
+ f.read()
+except OSError as e:
+ print(e.args[0] == uerrno.EINVAL)
+
+try:
+ f.flush()
+except OSError as e:
+ print(e.args[0] == uerrno.EINVAL)
+
+try:
+ open("foo_file.txt", "x")
+except OSError as e:
+ print(e.args[0] == uerrno.EEXIST)
+
+with open("foo_file.txt", "a") as f:
+ f.write("world!")
+
+with open("foo_file.txt") as f2:
+ print(f2.read())
+ print(f2.tell())
+
+ f2.seek(0, 0) # SEEK_SET
+ print(f2.read(1))
+
+ f2.seek(0, 1) # SEEK_CUR
+ print(f2.read(1))
+ try:
+ f2.seek(1, 1) # SEEK_END
+ except OSError as e:
+ print(e.args[0] == uerrno.EOPNOTSUPP)
+
+ f2.seek(-2, 2) # SEEK_END
+ print(f2.read(1))
+
+# using constructor of FileIO type to open a file
+# no longer working with new VFS sub-system
+#FileIO = type(f)
+#with FileIO("/ramdisk/foo_file.txt") as f:
+# print(f.read())
+
+# dirs
+vfs.mkdir("foo_dir")
+
+try:
+ vfs.rmdir("foo_file.txt")
+except OSError as e:
+ print(e.args[0] == 20) # uerrno.ENOTDIR
+
+vfs.remove("foo_file.txt")
+print(list(vfs.ilistdir()))
diff --git a/tests/extmod/vfs_fat_fileio1.py.exp b/tests/extmod/vfs_fat_fileio1.py.exp
new file mode 100644
index 000000000..d777585cf
--- /dev/null
+++ b/tests/extmod/vfs_fat_fileio1.py.exp
@@ -0,0 +1,13 @@
+<io.TextIOWrapper >
+True
+True
+True
+True
+hello!world!
+12
+h
+e
+True
+d
+True
+[('foo_dir', 16384, 0)]
diff --git a/tests/extmod/vfs_fat_fileio.py b/tests/extmod/vfs_fat_fileio2.py
index f050d94e2..b2a0ba70f 100644
--- a/tests/extmod/vfs_fat_fileio.py
+++ b/tests/extmod/vfs_fat_fileio2.py
@@ -1,6 +1,15 @@
import sys
-import uos
-import uerrno
+try:
+ import uerrno
+ try:
+ import uos_vfs as uos
+ open = uos.vfs_open
+ except ImportError:
+ import uos
+except ImportError:
+ print("SKIP")
+ sys.exit()
+
try:
uos.VfsFat
except AttributeError:
@@ -34,73 +43,15 @@ class RAMFS:
try:
- bdev = RAMFS(48)
+ bdev = RAMFS(50)
except MemoryError:
print("SKIP")
sys.exit()
uos.VfsFat.mkfs(bdev)
-vfs = uos.VfsFat(bdev, "/ramdisk")
-
-# file IO
-f = vfs.open("foo_file.txt", "w")
-print(str(f)[:17], str(f)[-1:])
-f.write("hello!")
-f.flush()
-f.close()
-f.close() # allowed
-try:
- f.write("world!")
-except OSError as e:
- print(e.args[0] == uerrno.EINVAL)
-
-try:
- f.read()
-except OSError as e:
- print(e.args[0] == uerrno.EINVAL)
-
-try:
- f.flush()
-except OSError as e:
- print(e.args[0] == uerrno.EINVAL)
-
-try:
- vfs.open("foo_file.txt", "x")
-except OSError as e:
- print(e.args[0] == uerrno.EEXIST)
-
-with vfs.open("foo_file.txt", "a") as f:
- f.write("world!")
-
-with vfs.open("foo_file.txt") as f2:
- print(f2.read())
- print(f2.tell())
-
- f2.seek(0, 0) # SEEK_SET
- print(f2.read(1))
-
- f2.seek(0, 1) # SEEK_CUR
- print(f2.read(1))
- try:
- f2.seek(1, 1) # SEEK_END
- except OSError as e:
- print(e.args[0] == uerrno.EOPNOTSUPP)
-
- f2.seek(-2, 2) # SEEK_END
- print(f2.read(1))
-
-# using constructor of FileIO type to open a file
-FileIO = type(f)
-with FileIO("foo_file.txt") as f:
- print(f.read())
-
-# dirs
-vfs.mkdir("foo_dir")
-
-try:
- vfs.rmdir("foo_file.txt")
-except OSError as e:
- print(e.args[0] == 20) # uerrno.ENOTDIR
+vfs = uos.VfsFat(bdev)
+uos.mount(vfs, '/ramdisk')
+uos.chdir('/ramdisk')
try:
vfs.mkdir("foo_dir")
@@ -118,18 +69,18 @@ except OSError as e:
print(e.args[0] == uerrno.ENOENT)
try:
- vfs.rename("foo_dir", "/null")
+ vfs.rename("foo_dir", "/null/file")
except OSError as e:
- print(e.args[0] == uerrno.ENODEV)
+ print(e.args[0] == uerrno.ENOENT)
# file in dir
-with vfs.open("foo_dir/file-in-dir.txt", "w+t") as f:
+with open("foo_dir/file-in-dir.txt", "w+t") as f:
f.write("data in file")
-with vfs.open("foo_dir/file-in-dir.txt", "r+b") as f:
+with open("foo_dir/file-in-dir.txt", "r+b") as f:
print(f.read())
-with vfs.open("foo_dir/sub_file.txt", "w") as f:
+with open("foo_dir/sub_file.txt", "w") as f:
f.write("subdir file")
# directory not empty
@@ -139,31 +90,30 @@ except OSError as e:
print(e.args[0] == uerrno.EACCES)
# trim full path
-vfs.rename("foo_dir/file-in-dir.txt", "/ramdisk/foo_dir/file.txt")
-print(vfs.listdir("foo_dir"))
+vfs.rename("foo_dir/file-in-dir.txt", "foo_dir/file.txt")
+print(list(vfs.ilistdir("foo_dir")))
vfs.rename("foo_dir/file.txt", "moved-to-root.txt")
-print(vfs.listdir())
+print(list(vfs.ilistdir()))
# check that renaming to existing file will overwrite it
-with vfs.open("temp", "w") as f:
+with open("temp", "w") as f:
f.write("new text")
vfs.rename("temp", "moved-to-root.txt")
-print(vfs.listdir())
-with vfs.open("moved-to-root.txt") as f:
+print(list(vfs.ilistdir()))
+with open("moved-to-root.txt") as f:
print(f.read())
# valid removes
vfs.remove("foo_dir/sub_file.txt")
-vfs.remove("foo_file.txt")
vfs.rmdir("foo_dir")
-print(vfs.listdir())
+print(list(vfs.ilistdir()))
# disk full
try:
bsize = vfs.statvfs("/ramdisk")[0]
free = vfs.statvfs("/ramdisk")[2] + 1
- f = vfs.open("large_file.txt", "wb")
+ f = open("large_file.txt", "wb")
f.write(bytearray(bsize * free))
except OSError as e:
print("ENOSPC:", e.args[0] == 28) # uerrno.ENOSPC
diff --git a/tests/extmod/vfs_fat_fileio2.py.exp b/tests/extmod/vfs_fat_fileio2.py.exp
new file mode 100644
index 000000000..118dee26b
--- /dev/null
+++ b/tests/extmod/vfs_fat_fileio2.py.exp
@@ -0,0 +1,11 @@
+True
+True
+True
+b'data in file'
+True
+[('sub_file.txt', 32768, 0), ('file.txt', 32768, 0)]
+[('foo_dir', 16384, 0), ('moved-to-root.txt', 32768, 0)]
+[('foo_dir', 16384, 0), ('moved-to-root.txt', 32768, 0)]
+new text
+[('moved-to-root.txt', 32768, 0)]
+ENOSPC: True
diff --git a/tests/extmod/vfs_fat_fsusermount.py b/tests/extmod/vfs_fat_fsusermount.py
deleted file mode 100644
index 7326172ee..000000000
--- a/tests/extmod/vfs_fat_fsusermount.py
+++ /dev/null
@@ -1,96 +0,0 @@
-import sys
-import uos
-import uerrno
-try:
- uos.VfsFat
-except AttributeError:
- print("SKIP")
- sys.exit()
-
-
-class RAMFS:
-
- SEC_SIZE = 512
-
- def __init__(self, blocks):
- self.data = bytearray(blocks * self.SEC_SIZE)
-
- def readblocks(self, n, buf):
- #print("readblocks(%s, %x(%d))" % (n, id(buf), len(buf)))
- for i in range(len(buf)):
- buf[i] = self.data[n * self.SEC_SIZE + i]
-
- def writeblocks(self, n, buf):
- #print("writeblocks(%s, %x)" % (n, id(buf)))
- for i in range(len(buf)):
- self.data[n * self.SEC_SIZE + i] = buf[i]
-
- def ioctl(self, op, arg):
- #print("ioctl(%d, %r)" % (op, arg))
- if op == 4: # BP_IOCTL_SEC_COUNT
- return len(self.data) // self.SEC_SIZE
- if op == 5: # BP_IOCTL_SEC_SIZE
- return self.SEC_SIZE
-
-
-try:
- bdev = RAMFS(48)
-except MemoryError:
- print("SKIP")
- sys.exit()
-
-# can't mkfs readonly device
-try:
- uos.vfs_mkfs(bdev, "/ramdisk", readonly=True)
-except OSError as e:
- print(e)
-
-# mount before mkfs
-try:
- uos.vfs_mount(bdev, "/ramdisk")
-except OSError as e:
- print(e)
-
-# invalid umount
-try:
- uos.vfs_umount("/ramdisk")
-except OSError as e:
- print(e.args[0] == uerrno.EINVAL)
-
-try:
- uos.vfs_mount(None, "/ramdisk")
-except OSError as e:
- print(e)
-
-try:
- uos.vfs_mkfs(None, "/ramdisk")
-except OSError as e:
- print(e)
-
-# valid mkfs/mount
-uos.vfs_mkfs(bdev, "/ramdisk")
-uos.vfs_mount(bdev, "/ramdisk")
-
-# umount by path
-uos.vfs_umount("/ramdisk")
-
-# readonly mount
-uos.vfs_mount(bdev, "/ramdisk", readonly=True)
-vfs = uos.VfsFat(bdev, "/ramdisk")
-try:
- f = vfs.open("file.txt", "w")
-except OSError as e:
- print("EROFS:", e.args[0] == 30) # uerrno.EROFS
-
-# device is None == umount
-uos.vfs_mount(None, "/ramdisk")
-
-# max mounted devices
-dev = []
-try:
- for i in range(0,4):
- dev.append(RAMFS(48))
- uos.vfs_mkfs(dev[i], "/ramdisk" + str(i))
- uos.vfs_mount(dev[i], "/ramdisk" + str(i))
-except OSError as e:
- print(e)
diff --git a/tests/extmod/vfs_fat_fsusermount.py.exp b/tests/extmod/vfs_fat_fsusermount.py.exp
deleted file mode 100644
index 3b30688dd..000000000
--- a/tests/extmod/vfs_fat_fsusermount.py.exp
+++ /dev/null
@@ -1,7 +0,0 @@
-can't mkfs
-can't mount
-True
-can't umount
-can't umount
-EROFS: True
-too many devices mounted
diff --git a/tests/extmod/vfs_fat_more.py b/tests/extmod/vfs_fat_more.py
new file mode 100644
index 000000000..dacb21553
--- /dev/null
+++ b/tests/extmod/vfs_fat_more.py
@@ -0,0 +1,117 @@
+import sys
+import uerrno
+try:
+ try:
+ import uos_vfs as uos
+ open = uos.vfs_open
+ except ImportError:
+ import uos
+except ImportError:
+ print("SKIP")
+ sys.exit()
+
+try:
+ uos.VfsFat
+except AttributeError:
+ print("SKIP")
+ sys.exit()
+
+
+class RAMFS:
+
+ SEC_SIZE = 512
+
+ def __init__(self, blocks):
+ self.data = bytearray(blocks * self.SEC_SIZE)
+
+ def readblocks(self, n, buf):
+ #print("readblocks(%s, %x(%d))" % (n, id(buf), len(buf)))
+ for i in range(len(buf)):
+ buf[i] = self.data[n * self.SEC_SIZE + i]
+
+ def writeblocks(self, n, buf):
+ #print("writeblocks(%s, %x)" % (n, id(buf)))
+ for i in range(len(buf)):
+ self.data[n * self.SEC_SIZE + i] = buf[i]
+
+ def ioctl(self, op, arg):
+ #print("ioctl(%d, %r)" % (op, arg))
+ if op == 4: # BP_IOCTL_SEC_COUNT
+ return len(self.data) // self.SEC_SIZE
+ if op == 5: # BP_IOCTL_SEC_SIZE
+ return self.SEC_SIZE
+
+
+try:
+ bdev = RAMFS(50)
+ bdev2 = RAMFS(50)
+except MemoryError:
+ print("SKIP")
+ sys.exit()
+
+# first we umount any existing mount points the target may have
+try:
+ uos.umount('/')
+except OSError:
+ pass
+for path in uos.listdir('/'):
+ uos.umount('/' + path)
+
+uos.VfsFat.mkfs(bdev)
+uos.mount(bdev, '/')
+
+print(uos.getcwd())
+
+f = open('test.txt', 'w')
+f.write('hello')
+f.close()
+
+print(uos.listdir())
+print(uos.listdir('/'))
+print(uos.stat('')[:-3])
+print(uos.stat('/')[:-3])
+print(uos.stat('test.txt')[:-3])
+print(uos.stat('/test.txt')[:-3])
+
+f = open('/test.txt')
+print(f.read())
+f.close()
+
+uos.rename('test.txt', 'test2.txt')
+print(uos.listdir())
+uos.rename('test2.txt', '/test3.txt')
+print(uos.listdir())
+uos.rename('/test3.txt', 'test4.txt')
+print(uos.listdir())
+uos.rename('/test4.txt', '/test5.txt')
+print(uos.listdir())
+
+uos.mkdir('dir')
+print(uos.listdir())
+uos.mkdir('/dir2')
+print(uos.listdir())
+uos.mkdir('dir/subdir')
+print(uos.listdir('dir'))
+for exist in ('', '/', 'dir', '/dir', 'dir/subdir'):
+ try:
+ uos.mkdir(exist)
+ except OSError as er:
+ print('mkdir OSError', er.args[0] == 17) # EEXIST
+
+uos.chdir('/')
+print(uos.stat('test5.txt')[:-3])
+
+uos.VfsFat.mkfs(bdev2)
+uos.mount(bdev2, '/sys')
+print(uos.listdir())
+print(uos.listdir('sys'))
+print(uos.listdir('/sys'))
+
+uos.rmdir('dir2')
+uos.remove('test5.txt')
+print(uos.listdir())
+
+uos.umount('/')
+print(uos.getcwd())
+print(uos.listdir())
+print(uos.listdir('sys'))
diff --git a/tests/extmod/vfs_fat_more.py.exp b/tests/extmod/vfs_fat_more.py.exp
new file mode 100644
index 000000000..aaca3cc75
--- /dev/null
+++ b/tests/extmod/vfs_fat_more.py.exp
@@ -0,0 +1,28 @@
+/
+['test.txt']
+['test.txt']
+(16384, 0, 0, 0, 0, 0, 0)
+(16384, 0, 0, 0, 0, 0, 0)
+(32768, 0, 0, 0, 0, 0, 5)
+(32768, 0, 0, 0, 0, 0, 5)
+hello
+['test2.txt']
+['test3.txt']
+['test4.txt']
+['test5.txt']
+['test5.txt', 'dir']
+['test5.txt', 'dir', 'dir2']
+['subdir']
+mkdir OSError True
+mkdir OSError True
+mkdir OSError True
+mkdir OSError True
+mkdir OSError True
+(32768, 0, 0, 0, 0, 0, 5)
+['sys', 'test5.txt', 'dir', 'dir2']
+[]
+[]
+['sys', 'dir']
+/
+['sys']
+[]
diff --git a/tests/extmod/vfs_fat_oldproto.py b/tests/extmod/vfs_fat_oldproto.py
index 73983567d..3e66758c3 100644
--- a/tests/extmod/vfs_fat_oldproto.py
+++ b/tests/extmod/vfs_fat_oldproto.py
@@ -1,10 +1,16 @@
import sys
-import uos
-import uerrno
+try:
+ import uerrno
+ try:
+ import uos_vfs as uos
+ except ImportError:
+ import uos
+except ImportError:
+ print("SKIP")
+ sys.exit()
+
try:
uos.VfsFat
- uos.vfs_mkfs
- uos.vfs_mount
except AttributeError:
print("SKIP")
sys.exit()
@@ -34,30 +40,23 @@ class RAMFS_OLD:
try:
- bdev = RAMFS_OLD(48)
+ bdev = RAMFS_OLD(50)
except MemoryError:
print("SKIP")
sys.exit()
-uos.vfs_mkfs(bdev, "/ramdisk")
-uos.vfs_mount(bdev, "/ramdisk")
+uos.VfsFat.mkfs(bdev)
+vfs = uos.VfsFat(bdev)
+uos.mount(vfs, "/ramdisk")
# file io
-vfs = uos.VfsFat(bdev, "/ramdisk")
with vfs.open("file.txt", "w") as f:
f.write("hello!")
-print(vfs.listdir())
+print(list(vfs.ilistdir()))
with vfs.open("file.txt", "r") as f:
print(f.read())
vfs.remove("file.txt")
-print(vfs.listdir())
-
-# umount by device
-uos.vfs_umount(bdev)
-try:
- vfs.listdir()
-except OSError as e:
- print(e.args[0] == uerrno.ENODEV)
+print(list(vfs.ilistdir()))
diff --git a/tests/extmod/vfs_fat_oldproto.py.exp b/tests/extmod/vfs_fat_oldproto.py.exp
index 4120c277a..ab8338cbb 100644
--- a/tests/extmod/vfs_fat_oldproto.py.exp
+++ b/tests/extmod/vfs_fat_oldproto.py.exp
@@ -1,4 +1,3 @@
-['file.txt']
+[('file.txt', 32768, 0)]
hello!
[]
-True
diff --git a/tests/extmod/vfs_fat_ramdisk.py b/tests/extmod/vfs_fat_ramdisk.py
index 184672ff1..fe72a8bef 100644
--- a/tests/extmod/vfs_fat_ramdisk.py
+++ b/tests/extmod/vfs_fat_ramdisk.py
@@ -1,6 +1,14 @@
import sys
-import uos
-import uerrno
+try:
+ import uerrno
+ try:
+ import uos_vfs as uos
+ except ImportError:
+ import uos
+except ImportError:
+ print("SKIP")
+ sys.exit()
+
try:
uos.VfsFat
except AttributeError:
@@ -34,7 +42,7 @@ class RAMFS:
try:
- bdev = RAMFS(48)
+ bdev = RAMFS(50)
except MemoryError:
print("SKIP")
sys.exit()
@@ -44,12 +52,8 @@ uos.VfsFat.mkfs(bdev)
print(b"FOO_FILETXT" not in bdev.data)
print(b"hello!" not in bdev.data)
-vfs = uos.VfsFat(bdev, "/ramdisk")
-
-try:
- vfs.statvfs("/null")
-except OSError as e:
- print(e.args[0] == uerrno.ENODEV)
+vfs = uos.VfsFat(bdev)
+uos.mount(vfs, "/ramdisk")
print("statvfs:", vfs.statvfs("/ramdisk"))
print("getcwd:", vfs.getcwd())
@@ -61,11 +65,10 @@ except OSError as e:
with vfs.open("foo_file.txt", "w") as f:
f.write("hello!")
-print(vfs.listdir())
+print(list(vfs.ilistdir()))
print("stat root:", vfs.stat("/"))
-print("stat disk:", vfs.stat("/ramdisk/"))
-print("stat file:", vfs.stat("foo_file.txt"))
+print("stat file:", vfs.stat("foo_file.txt")[:-3]) # timestamps differ across runs
print(b"FOO_FILETXT" in bdev.data)
print(b"hello!" in bdev.data)
@@ -73,7 +76,7 @@ print(b"hello!" in bdev.data)
vfs.mkdir("foo_dir")
vfs.chdir("foo_dir")
print("getcwd:", vfs.getcwd())
-print(vfs.listdir())
+print(list(vfs.ilistdir()))
with vfs.open("sub_file.txt", "w") as f:
f.write("subdir file")
@@ -86,16 +89,13 @@ except OSError as e:
vfs.chdir("..")
print("getcwd:", vfs.getcwd())
-vfs.umount()
-try:
- vfs.listdir()
-except OSError as e:
- print(e.args[0] == uerrno.ENODEV)
+uos.umount(vfs)
+vfs = uos.VfsFat(bdev)
+print(list(vfs.ilistdir(b"")))
+
+# list a non-existent directory
try:
- vfs.getcwd()
+ vfs.ilistdir(b"no_exist")
except OSError as e:
- print(e.args[0] == uerrno.ENODEV)
-
-vfs = uos.VfsFat(bdev, "/ramdisk")
-print(vfs.listdir(b""))
+ print('ENOENT:', e.args[0] == uerrno.ENOENT)
diff --git a/tests/extmod/vfs_fat_ramdisk.py.exp b/tests/extmod/vfs_fat_ramdisk.py.exp
index eaf637199..ccd0f7134 100644
--- a/tests/extmod/vfs_fat_ramdisk.py.exp
+++ b/tests/extmod/vfs_fat_ramdisk.py.exp
@@ -1,19 +1,16 @@
True
True
+statvfs: (512, 512, 16, 16, 16, 0, 0, 0, 0, 255)
+getcwd: /
True
-statvfs: (512, 512, 14, 14, 14, 0, 0, 0, 0, 255)
-getcwd: /ramdisk
-True
-['foo_file.txt']
+[('foo_file.txt', 32768, 0)]
stat root: (16384, 0, 0, 0, 0, 0, 0, 0, 0, 0)
-stat disk: (16384, 0, 0, 0, 0, 0, 0, 0, 0, 0)
-stat file: (32768, 0, 0, 0, 0, 0, 6, -631238400, -631238400, -631238400)
+stat file: (32768, 0, 0, 0, 0, 0, 6)
True
True
-getcwd: /ramdisk/foo_dir
+getcwd: /foo_dir
[]
True
-getcwd: /ramdisk
-True
-True
-[b'foo_file.txt', b'foo_dir']
+getcwd: /
+[(b'foo_file.txt', 32768, 0), (b'foo_dir', 16384, 0)]
+ENOENT: True
diff --git a/tests/extmod/websocket_basic.py b/tests/extmod/websocket_basic.py
new file mode 100644
index 000000000..770836c8e
--- /dev/null
+++ b/tests/extmod/websocket_basic.py
@@ -0,0 +1,61 @@
+try:
+ import uio
+ import uerrno
+ import websocket
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+# put raw data in the stream and do a websocket read
+def ws_read(msg, sz):
+ ws = websocket.websocket(uio.BytesIO(msg))
+ return ws.read(sz)
+
+# do a websocket write and then return the raw data from the stream
+def ws_write(msg, sz):
+ s = uio.BytesIO()
+ ws = websocket.websocket(s)
+ ws.write(msg)
+ s.seek(0)
+ return s.read(sz)
+
+# basic frame
+print(ws_read(b"\x81\x04ping", 4))
+print(ws_read(b"\x80\x04ping", 4)) # FRAME_CONT
+print(ws_write(b"pong", 6))
+
+# split frames are not supported
+# print(ws_read(b"\x01\x04ping", 4))
+
+# extended payloads
+print(ws_read(b'\x81~\x00\x80' + b'ping' * 32, 128))
+print(ws_write(b"pong" * 32, 132))
+
+# mask (returned data will be 'mask' ^ 'mask')
+print(ws_read(b"\x81\x84maskmask", 4))
+
+# close control frame
+s = uio.BytesIO(b'\x88\x00') # FRAME_CLOSE
+ws = websocket.websocket(s)
+print(ws.read(1))
+s.seek(2)
+print(s.read(4))
+
+# misc control frames
+print(ws_read(b"\x89\x00\x81\x04ping", 4)) # FRAME_PING
+print(ws_read(b"\x8a\x00\x81\x04pong", 4)) # FRAME_PONG
+
+# close method
+ws = websocket.websocket(uio.BytesIO())
+ws.close()
+
+# ioctl
+ws = websocket.websocket(uio.BytesIO())
+print(ws.ioctl(8)) # GET_DATA_OPTS
+print(ws.ioctl(9, 2)) # SET_DATA_OPTS
+print(ws.ioctl(9))
+try:
+ ws.ioctl(-1)
+except OSError as e:
+ print("ioctl: EINVAL:", e.args[0] == uerrno.EINVAL)
diff --git a/tests/extmod/websocket_basic.py.exp b/tests/extmod/websocket_basic.py.exp
new file mode 100644
index 000000000..2d7657b53
--- /dev/null
+++ b/tests/extmod/websocket_basic.py.exp
@@ -0,0 +1,14 @@
+b'ping'
+b'ping'
+b'\x81\x04pong'
+b'pingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingping'
+b'\x81~\x00\x80pongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpong'
+b'\x00\x00\x00\x00'
+b''
+b'\x81\x02\x88\x00'
+b'ping'
+b'pong'
+0
+1
+2
+ioctl: EINVAL: True
diff --git a/tests/feature_check/async_check.py b/tests/feature_check/async_check.py
new file mode 100644
index 000000000..0f6361cd1
--- /dev/null
+++ b/tests/feature_check/async_check.py
@@ -0,0 +1,3 @@
+# check if async/await keywords are supported
+async def foo():
+ await 1
diff --git a/tests/feature_check/async_check.py.exp b/tests/feature_check/async_check.py.exp
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/feature_check/async_check.py.exp
diff --git a/tests/feature_check/const.py b/tests/feature_check/const.py
new file mode 100644
index 000000000..db32e8c69
--- /dev/null
+++ b/tests/feature_check/const.py
@@ -0,0 +1 @@
+x = const(1)
diff --git a/tests/feature_check/const.py.exp b/tests/feature_check/const.py.exp
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/feature_check/const.py.exp
diff --git a/tests/feature_check/int_big.py b/tests/feature_check/int_big.py
new file mode 100644
index 000000000..f30285a98
--- /dev/null
+++ b/tests/feature_check/int_big.py
@@ -0,0 +1,2 @@
+# Check whether arbitrary-precision integers (MPZ) are supported
+print(1000000000000000000000000000000000000000000000)
diff --git a/tests/feature_check/int_big.py.exp b/tests/feature_check/int_big.py.exp
new file mode 100644
index 000000000..9dfe3354d
--- /dev/null
+++ b/tests/feature_check/int_big.py.exp
@@ -0,0 +1 @@
+1000000000000000000000000000000000000000000000
diff --git a/tests/float/array_construct.py b/tests/float/array_construct.py
index a25cc72c8..7e01fd476 100644
--- a/tests/float/array_construct.py
+++ b/tests/float/array_construct.py
@@ -1,6 +1,11 @@
# test construction of array from array with float type
-from array import array
+try:
+ from array import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
print(array('f', array('h', [1, 2])))
print(array('d', array('f', [1, 2])))
diff --git a/tests/float/builtin_float_hash.py b/tests/float/builtin_float_hash.py
new file mode 100644
index 000000000..ba6b63907
--- /dev/null
+++ b/tests/float/builtin_float_hash.py
@@ -0,0 +1,22 @@
+# test builtin hash function with float args
+
+# these should hash to an integer with a specific value
+for val in (
+ '0.0',
+ '1.0',
+ '2.0',
+ '-12.0',
+ '12345.0',
+ ):
+ print(val, hash(float(val)))
+
+# just check that these values are hashable
+for val in (
+ '0.1',
+ '-0.1',
+ '10.3',
+ 'inf',
+ '-inf',
+ 'nan',
+ ):
+ print(val, type(hash(float(val))))
diff --git a/tests/float/builtin_float_minmax.py b/tests/float/builtin_float_minmax.py
index ce45a768a..42cfa6382 100644
--- a/tests/float/builtin_float_minmax.py
+++ b/tests/float/builtin_float_minmax.py
@@ -1,4 +1,11 @@
# test builtin min and max functions with float args
+try:
+ min
+ max
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
print(min(0,1.0))
print(min(1.0,0))
diff --git a/tests/float/builtin_float_round.py b/tests/float/builtin_float_round.py
index de72514db..63cb39aa3 100644
--- a/tests/float/builtin_float_round.py
+++ b/tests/float/builtin_float_round.py
@@ -15,3 +15,10 @@ for i in range(11):
# test second arg
for i in range(-1, 3):
print(round(1.47, i))
+
+# test inf and nan
+for val in (float('inf'), float('nan')):
+ try:
+ round(val)
+ except (ValueError, OverflowError) as e:
+ print(type(e))
diff --git a/tests/float/builtin_float_round_intbig.py b/tests/float/builtin_float_round_intbig.py
new file mode 100644
index 000000000..2083e3ea3
--- /dev/null
+++ b/tests/float/builtin_float_round_intbig.py
@@ -0,0 +1,4 @@
+# test round() with floats that return large integers
+
+for x in (-1e25, 1e25):
+ print('%.3g' % round(x))
diff --git a/tests/float/bytearray_construct.py b/tests/float/bytearray_construct.py
index f72926635..db946a99d 100644
--- a/tests/float/bytearray_construct.py
+++ b/tests/float/bytearray_construct.py
@@ -1,5 +1,10 @@
# test construction of bytearray from array with float type
-from array import array
+try:
+ from array import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
print(bytearray(array('f', [1, 2.3])))
diff --git a/tests/float/bytes_construct.py b/tests/float/bytes_construct.py
index 0a57e08a2..8664d7296 100644
--- a/tests/float/bytes_construct.py
+++ b/tests/float/bytes_construct.py
@@ -1,5 +1,10 @@
# test construction of bytearray from array with float type
-from array import array
+try:
+ from array import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
print(bytes(array('f', [1, 2.3])))
diff --git a/tests/float/complex1.py b/tests/float/complex1.py
index 027d12583..a6038de04 100644
--- a/tests/float/complex1.py
+++ b/tests/float/complex1.py
@@ -28,6 +28,7 @@ print(1j / 2)
print((1j / 2j).real)
print(1j / (1 + 2j))
ans = 0j ** 0; print("%.5g %.5g" % (ans.real, ans.imag))
+ans = 0j ** 1; print("%.5g %.5g" % (ans.real, ans.imag))
ans = 0j ** 0j; print("%.5g %.5g" % (ans.real, ans.imag))
ans = 1j ** 2.5; print("%.5g %.5g" % (ans.real, ans.imag))
ans = 1j ** 2.5j; print("%.5g %.5g" % (ans.real, ans.imag))
@@ -40,6 +41,10 @@ print(1j == 1j)
print(abs(1j))
print("%.5g" % abs(1j + 2))
+# builtin hash
+print(hash(1 + 0j))
+print(type(hash(1j)))
+
# float on lhs should delegate to complex
print(1.2 + 3j)
@@ -48,8 +53,11 @@ print(float('nan') * 1j)
print(float('inf') * (1 + 1j))
print(float('-inf') * (1 + 1j))
-# convert bignum to complex on rhs
-ans = 1j + (1 << 70); print("%.5g %.5g" % (ans.real, ans.imag))
+# can't assign to attributes
+try:
+ (1j).imag = 0
+except AttributeError:
+ print('AttributeError')
# can't convert rhs to complex
try:
@@ -89,6 +97,10 @@ except ZeroDivisionError:
# zero division via power
try:
+ 0j ** -1
+except ZeroDivisionError:
+ print("ZeroDivisionError")
+try:
0j ** 1j
except ZeroDivisionError:
print("ZeroDivisionError")
diff --git a/tests/float/complex1_intbig.py b/tests/float/complex1_intbig.py
new file mode 100644
index 000000000..ed2390bba
--- /dev/null
+++ b/tests/float/complex1_intbig.py
@@ -0,0 +1,4 @@
+# test basic complex number functionality
+
+# convert bignum to complex on rhs
+ans = 1j + (1 << 70); print("%.5g %.5g" % (ans.real, ans.imag))
diff --git a/tests/float/float1.py b/tests/float/float1.py
index 0e115032b..93f6f014c 100644
--- a/tests/float/float1.py
+++ b/tests/float/float1.py
@@ -75,6 +75,11 @@ try:
except ZeroDivisionError:
print("ZeroDivisionError")
+try:
+ 0.0 ** -1
+except ZeroDivisionError:
+ print("ZeroDivisionError")
+
# unsupported unary ops
try:
diff --git a/tests/float/float2int_doubleprec.py b/tests/float/float2int_doubleprec_intbig.py
index acdc8c69c..de2137d66 100644
--- a/tests/float/float2int_doubleprec.py
+++ b/tests/float/float2int_doubleprec_intbig.py
@@ -5,21 +5,29 @@ try:
except:
import struct
+import sys
+maxsize_bits = 0
+maxsize = sys.maxsize
+while maxsize:
+ maxsize >>= 1
+ maxsize_bits += 1
+
# work out configuration values
-is_64bit = struct.calcsize("P") == 8
+is_64bit = maxsize_bits > 32
# 0 = none, 1 = long long, 2 = mpz
-try:
- dummy = 0x7fffffffffffffff
- try:
- if (0xffffffffffffffff + 1) > 0:
- ll_type = 2
- else:
- ll_type = 1
- except:
- # in case the sum in the if statement above changes to raising an exception on overflow
+ll_type = None
+if is_64bit:
+ if maxsize_bits < 63:
+ ll_type = 0
+else:
+ if maxsize_bits < 31:
+ ll_type = 0
+if ll_type is None:
+ one = 1
+ if one << 65 < one << 62:
ll_type = 1
-except:
- ll_type = 0
+ else:
+ ll_type = 2
# This case occurs with time.time() values
if ll_type != 0:
diff --git a/tests/float/float2int_fp30.py b/tests/float/float2int_fp30_intbig.py
index bad9c31e9..fbb94a4cc 100644
--- a/tests/float/float2int_fp30.py
+++ b/tests/float/float2int_fp30_intbig.py
@@ -5,21 +5,29 @@ try:
except:
import struct
+import sys
+maxsize_bits = 0
+maxsize = sys.maxsize
+while maxsize:
+ maxsize >>= 1
+ maxsize_bits += 1
+
# work out configuration values
-is_64bit = struct.calcsize("P") == 8
+is_64bit = maxsize_bits > 32
# 0 = none, 1 = long long, 2 = mpz
-try:
- dummy = 0x7fffffffffffffff
- try:
- if (0xffffffffffffffff + 1) > 0:
- ll_type = 2
- else:
- ll_type = 1
- except:
- # in case the sum in the if statement above changes to raising an exception on overflow
+ll_type = None
+if is_64bit:
+ if maxsize_bits < 63:
+ ll_type = 0
+else:
+ if maxsize_bits < 31:
+ ll_type = 0
+if ll_type is None:
+ one = 1
+ if one << 65 < one << 62:
ll_type = 1
-except:
- ll_type = 0
+ else:
+ ll_type = 2
# basic conversion
print(int(14187744.))
diff --git a/tests/float/float2int.py b/tests/float/float2int_intbig.py
index da530cee6..3596d2f73 100644
--- a/tests/float/float2int.py
+++ b/tests/float/float2int_intbig.py
@@ -5,21 +5,31 @@ try:
except:
import struct
+import sys
+
+maxsize_bits = 0
+maxsize = sys.maxsize
+while maxsize:
+ maxsize >>= 1
+ maxsize_bits += 1
+
# work out configuration values
-is_64bit = struct.calcsize("P") == 8
+is_64bit = maxsize_bits > 32
# 0 = none, 1 = long long, 2 = mpz
-try:
- dummy = 0x7fffffffffffffff
- try:
- if (0xffffffffffffffff + 1) > 0:
- ll_type = 2
- else:
- ll_type = 1
- except:
- # in case the sum in the if statement above changes to raising an exception on overflow
+ll_type = None
+if is_64bit:
+ if maxsize_bits < 63:
+ ll_type = 0
+else:
+ if maxsize_bits < 31:
+ ll_type = 0
+if ll_type is None:
+ one = 1
+ if one << 65 < one << 62:
ll_type = 1
-except:
- ll_type = 0
+ else:
+ ll_type = 2
+
# basic conversion
print(int(14187745.))
diff --git a/tests/float/float_array.py b/tests/float/float_array.py
index 033877db3..8bc963444 100644
--- a/tests/float/float_array.py
+++ b/tests/float/float_array.py
@@ -1,4 +1,9 @@
-from array import array
+try:
+ from array import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
def test(a):
print(a)
diff --git a/tests/float/float_struct.py b/tests/float/float_struct.py
index e55890a2c..a36ccce38 100644
--- a/tests/float/float_struct.py
+++ b/tests/float/float_struct.py
@@ -1,9 +1,13 @@
# test struct package with floats
-
try:
- import ustruct as struct
-except:
- import struct
+ try:
+ import ustruct as struct
+ except:
+ import struct
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
i = 1. + 1/2
# TODO: it looks like '=' format modifier is not yet supported
diff --git a/tests/float/int_divzero.py b/tests/float/int_divzero.py
index b037dd8c7..b311a1dbc 100644
--- a/tests/float/int_divzero.py
+++ b/tests/float/int_divzero.py
@@ -2,3 +2,8 @@ try:
1 / 0
except ZeroDivisionError:
print("ZeroDivisionError")
+
+try:
+ 0 ** -1
+except ZeroDivisionError:
+ print("ZeroDivisionError")
diff --git a/tests/float/math_fun_int.py b/tests/float/math_fun_int.py
new file mode 100644
index 000000000..ee54f0995
--- /dev/null
+++ b/tests/float/math_fun_int.py
@@ -0,0 +1,15 @@
+# test the math functions that return ints
+
+try:
+ import math
+except ImportError:
+ print("SKIP")
+ import sys
+ sys.exit()
+
+for fun in (math.ceil, math.floor, math.trunc):
+ for x in (-1.6, -0.2, 0, 0.6, 1.4, float('inf'), float('nan')):
+ try:
+ print(fun(x))
+ except (ValueError, OverflowError) as e:
+ print(type(e))
diff --git a/tests/float/math_fun_intbig.py b/tests/float/math_fun_intbig.py
new file mode 100644
index 000000000..962c10daa
--- /dev/null
+++ b/tests/float/math_fun_intbig.py
@@ -0,0 +1,12 @@
+# test the math functions that return ints, with very large results
+
+try:
+ import math
+except ImportError:
+ print("SKIP")
+ import sys
+ sys.exit()
+
+for fun in (math.ceil, math.floor, math.trunc):
+ for x in (-1e25, 1e25):
+ print('%.3g' % fun(x))
diff --git a/tests/float/string_format_modulo2.py b/tests/float/string_format_modulo2.py
index d35f2a2c0..f6b1ae537 100644
--- a/tests/float/string_format_modulo2.py
+++ b/tests/float/string_format_modulo2.py
@@ -18,7 +18,7 @@ def test(num, num_str):
# check pure zero
test(0.0, '0.0')
-# check most powers of 10, making sure to include exponents with 3 digits
-for e in range(-101, 102):
+# check some powers of 10, making sure to include exponents with 3 digits
+for e in range(-8, 8):
num = pow(10, e)
test(num, '1e%d' % e)
diff --git a/tests/float/string_format_modulo2_intbig.py b/tests/float/string_format_modulo2_intbig.py
new file mode 100644
index 000000000..9992ba65d
--- /dev/null
+++ b/tests/float/string_format_modulo2_intbig.py
@@ -0,0 +1,21 @@
+# test formatting floats with large precision, that it doesn't overflow the buffer
+
+def test(num, num_str):
+ if num == float('inf') or num == 0.0 and num_str != '0.0':
+ # skip numbers that overflow or underflow the FP precision
+ return
+ for kind in ('e', 'f', 'g'):
+ # check precision either side of the size of the buffer (32 bytes)
+ for prec in range(23, 36, 2):
+ fmt = '%.' + '%d' % prec + kind
+ s = fmt % num
+ check = abs(float(s) - num)
+ if num > 1:
+ check /= num
+ if check > 1e-6:
+ print('FAIL', num_str, fmt, s, len(s), check)
+
+# check most powers of 10, making sure to include exponents with 3 digits
+for e in range(-101, 102):
+ num = pow(10, e)
+ test(num, '1e%d' % e)
diff --git a/tests/import/import_pkg7.py b/tests/import/import_pkg7.py
index be8564ef6..e1463ebbf 100644
--- a/tests/import/import_pkg7.py
+++ b/tests/import/import_pkg7.py
@@ -1,2 +1,2 @@
-# This tests ... relative imports as used in pkg7
+# This tests ... relative imports as used in pkg7 and imports beyond package root
import pkg7.subpkg1.subpkg2.mod3
diff --git a/tests/import/import_pkg8.py b/tests/import/import_pkg8.py
new file mode 100644
index 000000000..4c1e832f2
--- /dev/null
+++ b/tests/import/import_pkg8.py
@@ -0,0 +1,2 @@
+# import with no __init__.py files
+import pkg8.mod
diff --git a/tests/import/pkg7/subpkg1/subpkg2/mod3.py b/tests/import/pkg7/subpkg1/subpkg2/mod3.py
index b85b34e60..7ed69bdee 100644
--- a/tests/import/pkg7/subpkg1/subpkg2/mod3.py
+++ b/tests/import/pkg7/subpkg1/subpkg2/mod3.py
@@ -2,3 +2,10 @@ from ... import mod1
from ...mod2 import bar
print(mod1.foo)
print(bar)
+
+# when attempting relative import beyond top-level package uPy raises ImportError
+# whereas CPython raises a ValueError
+try:
+ from .... import mod1
+except ValueError:
+ print('ValueError')
diff --git a/tests/import/pkg8/mod.py b/tests/import/pkg8/mod.py
new file mode 100644
index 000000000..b98f02ce6
--- /dev/null
+++ b/tests/import/pkg8/mod.py
@@ -0,0 +1 @@
+print('foo')
diff --git a/tests/io/buffered_writer.py b/tests/io/buffered_writer.py
index afeaa839c..bb7b4e8db 100644
--- a/tests/io/buffered_writer.py
+++ b/tests/io/buffered_writer.py
@@ -20,3 +20,9 @@ buf.flush()
print(bts.getvalue())
buf.flush()
print(bts.getvalue())
+
+# special case when alloc is a factor of total buffer length
+bts = io.BytesIO()
+buf = io.BufferedWriter(bts, 1)
+buf.write(b"foo")
+print(bts.getvalue())
diff --git a/tests/io/buffered_writer.py.exp b/tests/io/buffered_writer.py.exp
index 1309487e1..d086935a9 100644
--- a/tests/io/buffered_writer.py.exp
+++ b/tests/io/buffered_writer.py.exp
@@ -2,3 +2,4 @@ b''
b'foobarfo'
b'foobarfoobar'
b'foobarfoobar'
+b'foo'
diff --git a/tests/io/bytesio_ext.py b/tests/io/bytesio_ext.py
index e827d1409..e454b2fd9 100644
--- a/tests/io/bytesio_ext.py
+++ b/tests/io/bytesio_ext.py
@@ -4,6 +4,10 @@ try:
except ImportError:
import io
+a = io.BytesIO(b"foobar")
+a.seek(10)
+print(a.read(10))
+
a = io.BytesIO()
print(a.seek(8))
a.write(b"123")
diff --git a/tests/io/resource_stream.py b/tests/io/resource_stream.py
new file mode 100644
index 000000000..86975f118
--- /dev/null
+++ b/tests/io/resource_stream.py
@@ -0,0 +1,15 @@
+import uio
+import sys
+
+try:
+ uio.resource_stream
+except AttributeError:
+ print('SKIP')
+ sys.exit()
+
+buf = uio.resource_stream("data", "file2")
+print(buf.read())
+
+# resource_stream(None, ...) look ups from current dir, hence sys.path[0] hack
+buf = uio.resource_stream(None, sys.path[0] + "/data/file2")
+print(buf.read())
diff --git a/tests/io/resource_stream.py.exp b/tests/io/resource_stream.py.exp
new file mode 100644
index 000000000..75404a347
--- /dev/null
+++ b/tests/io/resource_stream.py.exp
@@ -0,0 +1,2 @@
+1234
+1234
diff --git a/tests/micropython/const_intbig.py b/tests/micropython/const_intbig.py
new file mode 100644
index 000000000..e74902652
--- /dev/null
+++ b/tests/micropython/const_intbig.py
@@ -0,0 +1,13 @@
+# test constant optimisation, with consts that are bignums
+
+from micropython import const
+
+# check we can make consts from bignums
+Z1 = const(0xffffffff)
+Z2 = const(0xffffffffffffffff)
+print(hex(Z1), hex(Z2))
+
+# check arithmetic with bignum
+Z3 = const(Z1 + Z2)
+Z4 = const((1 << 100) + Z1)
+print(hex(Z3), hex(Z4))
diff --git a/tests/micropython/const_intbig.py.exp b/tests/micropython/const_intbig.py.exp
new file mode 100644
index 000000000..137f86cf8
--- /dev/null
+++ b/tests/micropython/const_intbig.py.exp
@@ -0,0 +1,2 @@
+0xffffffff 0xffffffffffffffff
+0x100000000fffffffe 0x100000000000000000ffffffff
diff --git a/tests/micropython/heapalloc_bytesio.py b/tests/micropython/heapalloc_bytesio.py
new file mode 100644
index 000000000..2a8d50abe
--- /dev/null
+++ b/tests/micropython/heapalloc_bytesio.py
@@ -0,0 +1,19 @@
+try:
+ import uio
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+import micropython
+
+data = b"1234" * 16
+buf = uio.BytesIO(64)
+
+micropython.heap_lock()
+
+buf.write(data)
+
+micropython.heap_unlock()
+
+print(buf.getvalue())
diff --git a/tests/micropython/heapalloc_bytesio.py.exp b/tests/micropython/heapalloc_bytesio.py.exp
new file mode 100644
index 000000000..675761c2b
--- /dev/null
+++ b/tests/micropython/heapalloc_bytesio.py.exp
@@ -0,0 +1 @@
+b'1234123412341234123412341234123412341234123412341234123412341234'
diff --git a/tests/micropython/heapalloc_exc_raise.py b/tests/micropython/heapalloc_exc_raise.py
new file mode 100644
index 000000000..d60e14ce5
--- /dev/null
+++ b/tests/micropython/heapalloc_exc_raise.py
@@ -0,0 +1,23 @@
+# Test that we can raise and catch (preallocated) exception
+# without memory allocation.
+import micropython
+
+e = ValueError("error")
+
+def func():
+ try:
+ # This works as is because traceback is not allocated
+ # if not possible (heap is locked, no memory). If heap
+ # is not locked, this would allocate a traceback entry.
+ # To avoid that, traceback should be warmed up (by raising
+ # it once after creation) and then cleared before each
+ # raise with:
+ # e.__traceback__ = None
+ raise e
+ except Exception as e2:
+ print(e2)
+
+micropython.heap_lock()
+func()
+print("ok")
+micropython.heap_unlock()
diff --git a/tests/micropython/heapalloc_exc_raise.py.exp b/tests/micropython/heapalloc_exc_raise.py.exp
new file mode 100644
index 000000000..1e9edc75d
--- /dev/null
+++ b/tests/micropython/heapalloc_exc_raise.py.exp
@@ -0,0 +1,2 @@
+error
+ok
diff --git a/tests/micropython/heapalloc_int_from_bytes.py b/tests/micropython/heapalloc_int_from_bytes.py
new file mode 100644
index 000000000..5fe50443a
--- /dev/null
+++ b/tests/micropython/heapalloc_int_from_bytes.py
@@ -0,0 +1,9 @@
+# Test that int.from_bytes() for small number of bytes generates
+# small int.
+import micropython
+
+micropython.heap_lock()
+print(int.from_bytes(b"1", "little"))
+print(int.from_bytes(b"12", "little"))
+print(int.from_bytes(b"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "little"))
+micropython.heap_unlock()
diff --git a/tests/micropython/heapalloc_int_from_bytes.py.exp b/tests/micropython/heapalloc_int_from_bytes.py.exp
new file mode 100644
index 000000000..5ac6a573f
--- /dev/null
+++ b/tests/micropython/heapalloc_int_from_bytes.py.exp
@@ -0,0 +1,3 @@
+49
+12849
+50
diff --git a/tests/micropython/heapalloc_iter.py b/tests/micropython/heapalloc_iter.py
new file mode 100644
index 000000000..45d3519e4
--- /dev/null
+++ b/tests/micropython/heapalloc_iter.py
@@ -0,0 +1,70 @@
+# test that iterating doesn't use the heap
+try:
+ import array
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
+
+try:
+ from micropython import heap_lock, heap_unlock
+except (ImportError, AttributeError):
+ heap_lock = heap_unlock = lambda:0
+
+def do_iter(l):
+ for i in l:
+ print(i)
+
+def gen_func():
+ yield 1
+ yield 2
+
+# pre-create collections to iterate over
+ba = bytearray(b'123')
+ar = array.array('H', (123, 456))
+t = (1, 2, 3)
+l = [1, 2]
+d = {1:2}
+s = set((1,))
+fs = frozenset((1,))
+g1 = (100 + x for x in range(2))
+g2 = gen_func()
+
+# test containment (both success and failure) with the heap locked
+heap_lock()
+print(49 in b'123', 255 in b'123')
+print(1 in t, -1 in t)
+print(1 in l, -1 in l)
+print(1 in d, -1 in d)
+print(1 in s, -1 in s)
+heap_unlock()
+
+# test unpacking with the heap locked
+unp0 = unp1 = unp2 = None # preallocate slots for globals
+heap_lock()
+unp0, unp1, unp2 = t
+print(unp0, unp1, unp2)
+heap_unlock()
+
+# test certain builtins with the heap locked
+heap_lock()
+print(all(t))
+print(any(t))
+print(min(t))
+print(max(t))
+print(sum(t))
+heap_unlock()
+
+# test iterating over collections with the heap locked
+heap_lock()
+do_iter(b'123')
+do_iter(ba)
+do_iter(ar)
+do_iter(t)
+do_iter(l)
+do_iter(d)
+do_iter(s)
+do_iter(fs)
+do_iter(g1)
+do_iter(g2)
+heap_unlock()
diff --git a/tests/micropython/heapalloc_str.py b/tests/micropython/heapalloc_str.py
new file mode 100644
index 000000000..39aa56ccd
--- /dev/null
+++ b/tests/micropython/heapalloc_str.py
@@ -0,0 +1,18 @@
+# String operations which don't require allocation
+import micropython
+
+micropython.heap_lock()
+
+# Concatenating empty string returns original string
+b"" + b""
+b"" + b"1"
+b"2" + b""
+
+"" + ""
+"" + "1"
+"2" + ""
+
+# If no replacements done, returns original string
+"foo".replace(",", "_")
+
+micropython.heap_unlock()
diff --git a/tests/micropython/heapalloc_str.py.exp b/tests/micropython/heapalloc_str.py.exp
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/micropython/heapalloc_str.py.exp
diff --git a/tests/micropython/heapalloc_super.py b/tests/micropython/heapalloc_super.py
new file mode 100644
index 000000000..1cf5293d2
--- /dev/null
+++ b/tests/micropython/heapalloc_super.py
@@ -0,0 +1,17 @@
+# test super() operations which don't require allocation
+import micropython
+
+class A:
+ def foo(self):
+ print('A foo')
+ return 42
+class B(A):
+ def foo(self):
+ print('B foo')
+ print(super().foo())
+
+b = B()
+
+micropython.heap_lock()
+b.foo()
+micropython.heap_unlock()
diff --git a/tests/micropython/heapalloc_super.py.exp b/tests/micropython/heapalloc_super.py.exp
new file mode 100644
index 000000000..5dabd0c7c
--- /dev/null
+++ b/tests/micropython/heapalloc_super.py.exp
@@ -0,0 +1,3 @@
+B foo
+A foo
+42
diff --git a/tests/micropython/heapalloc_traceback.py b/tests/micropython/heapalloc_traceback.py
index 808df0225..b3795293f 100644
--- a/tests/micropython/heapalloc_traceback.py
+++ b/tests/micropython/heapalloc_traceback.py
@@ -2,7 +2,12 @@
import micropython
import sys
-import uio
+try:
+ import uio
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
# preallocate exception instance with some room for a traceback
global_exc = StopIteration()
diff --git a/tests/micropython/heapalloc_traceback.py.exp b/tests/micropython/heapalloc_traceback.py.exp
index 9ba10948d..facd0af13 100644
--- a/tests/micropython/heapalloc_traceback.py.exp
+++ b/tests/micropython/heapalloc_traceback.py.exp
@@ -1,5 +1,5 @@
StopIteration
Traceback (most recent call last):
- File , line 18, in test
+ File , line 23, in test
StopIteration:
diff --git a/tests/micropython/kbd_intr.py b/tests/micropython/kbd_intr.py
new file mode 100644
index 000000000..a7ce7464b
--- /dev/null
+++ b/tests/micropython/kbd_intr.py
@@ -0,0 +1,13 @@
+# test the micropython.kbd_intr() function
+
+import micropython
+
+try:
+ micropython.kbd_intr
+except AttributeError:
+ print('SKIP')
+ import sys
+ sys.exit()
+
+# just check we can actually call it
+micropython.kbd_intr(3)
diff --git a/tests/micropython/kbd_intr.py.exp b/tests/micropython/kbd_intr.py.exp
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/micropython/kbd_intr.py.exp
diff --git a/tests/micropython/native_const.py b/tests/micropython/native_const_intbig.py
index 611b39d8f..611b39d8f 100644
--- a/tests/micropython/native_const.py
+++ b/tests/micropython/native_const_intbig.py
diff --git a/tests/micropython/native_const.py.exp b/tests/micropython/native_const_intbig.py.exp
index 1d52d220f..1d52d220f 100644
--- a/tests/micropython/native_const.py.exp
+++ b/tests/micropython/native_const_intbig.py.exp
diff --git a/tests/micropython/opt_level.py b/tests/micropython/opt_level.py
index 4e2f2f4ea..5a10047f0 100644
--- a/tests/micropython/opt_level.py
+++ b/tests/micropython/opt_level.py
@@ -12,3 +12,8 @@ exec('print(__debug__)')
micropython.opt_level(1)
exec('print(__debug__)')
exec('assert 0')
+
+# check that level 3 doesn't store line numbers
+# the expected output is that any line is printed as "line 1"
+micropython.opt_level(3)
+exec('try:\n xyz\nexcept NameError as er:\n import sys\n sys.print_exception(er)')
diff --git a/tests/micropython/opt_level.py.exp b/tests/micropython/opt_level.py.exp
index 74b3dd74e..9b1bb4d24 100644
--- a/tests/micropython/opt_level.py.exp
+++ b/tests/micropython/opt_level.py.exp
@@ -2,3 +2,6 @@
1
True
False
+Traceback (most recent call last):
+ File "<string>", line 1, in <module>
+NameError: name 'xyz' is not defined
diff --git a/tests/micropython/schedule.py b/tests/micropython/schedule.py
new file mode 100644
index 000000000..3d584eea4
--- /dev/null
+++ b/tests/micropython/schedule.py
@@ -0,0 +1,61 @@
+# test micropython.schedule() function
+
+import micropython
+
+try:
+ micropython.schedule
+except AttributeError:
+ print('SKIP')
+ import sys
+ sys.exit()
+
+# Basic test of scheduling a function.
+
+def callback(arg):
+ global done
+ print(arg)
+ done = True
+
+done = False
+micropython.schedule(callback, 1)
+while not done:
+ pass
+
+# Test that callbacks can be scheduled from within a callback, but
+# that they don't execute until the outer callback is finished.
+
+def callback_inner(arg):
+ global done
+ print('inner')
+ done += 1
+
+def callback_outer(arg):
+ global done
+ micropython.schedule(callback_inner, 0)
+ # need a loop so that the VM can check for pending events
+ for i in range(2):
+ pass
+ print('outer')
+ done += 1
+
+done = 0
+micropython.schedule(callback_outer, 0)
+while done != 2:
+ pass
+
+# Test that scheduling too many callbacks leads to an exception. To do this we
+# must schedule from within a callback to guarantee that the scheduler is locked.
+
+def callback(arg):
+ global done
+ try:
+ for i in range(100):
+ micropython.schedule(lambda x:x, None)
+ except RuntimeError:
+ print('RuntimeError')
+ done = True
+
+done = False
+micropython.schedule(callback, None)
+while not done:
+ pass
diff --git a/tests/micropython/schedule.py.exp b/tests/micropython/schedule.py.exp
new file mode 100644
index 000000000..c4a3e1227
--- /dev/null
+++ b/tests/micropython/schedule.py.exp
@@ -0,0 +1,4 @@
+1
+outer
+inner
+RuntimeError
diff --git a/tests/micropython/viper_error.py b/tests/micropython/viper_error.py
index 116bd4ea0..847257285 100644
--- a/tests/micropython/viper_error.py
+++ b/tests/micropython/viper_error.py
@@ -3,13 +3,19 @@
def test(code):
try:
exec(code)
- except (SyntaxError, ViperTypeError) as e:
+ except (SyntaxError, ViperTypeError, NotImplementedError) as e:
print(repr(e))
# viper: annotations must be identifiers
test("@micropython.viper\ndef f(a:1): pass")
test("@micropython.viper\ndef f() -> 1: pass")
+# unknown type
+test("@micropython.viper\ndef f(x:unknown_type): pass")
+
+# too many arguments
+test("@micropython.viper\ndef f(a, b, c, d, e): pass")
+
# local used before type known
test("""
@micropython.viper
@@ -49,6 +55,9 @@ test("@micropython.viper\ndef f(): 1[x]")
# can't store
test("@micropython.viper\ndef f(): 1[0] = 1")
test("@micropython.viper\ndef f(): 1[x] = 1")
+test("@micropython.viper\ndef f(x:int): x[0] = x")
+test("@micropython.viper\ndef f(x:ptr32): x[0] = None")
+test("@micropython.viper\ndef f(x:ptr32): x[x] = None")
# must raise an object
test("@micropython.viper\ndef f(): raise 1")
@@ -57,3 +66,16 @@ test("@micropython.viper\ndef f(): raise 1")
test("@micropython.viper\ndef f(x:int): +x")
test("@micropython.viper\ndef f(x:int): -x")
test("@micropython.viper\ndef f(x:int): ~x")
+
+# binary op not implemented
+test("@micropython.viper\ndef f(x:int): res = x in x")
+
+# yield (from) not implemented
+test("@micropython.viper\ndef f(): yield")
+test("@micropython.viper\ndef f(): yield from f")
+
+# passing a ptr to a Python function not implemented
+test("@micropython.viper\ndef f(): print(ptr(1))")
+
+# cast of a casting identifier not implemented
+test("@micropython.viper\ndef f(): int(int)")
diff --git a/tests/micropython/viper_error.py.exp b/tests/micropython/viper_error.py.exp
index 1afcd4bdb..96be5a590 100644
--- a/tests/micropython/viper_error.py.exp
+++ b/tests/micropython/viper_error.py.exp
@@ -1,5 +1,7 @@
SyntaxError('parameter annotation must be an identifier',)
SyntaxError('return annotation must be an identifier',)
+ViperTypeError("unknown type 'unknown_type'",)
+ViperTypeError("Viper functions don't currently support more than 4 arguments",)
ViperTypeError("local 'x' used before type known",)
ViperTypeError("local 'x' has type 'int' but source is 'object'",)
ViperTypeError("can't implicitly convert 'ptr' to 'bool'",)
@@ -9,7 +11,15 @@ ViperTypeError("can't load from 'int'",)
ViperTypeError("can't load from 'int'",)
ViperTypeError("can't store to 'int'",)
ViperTypeError("can't store to 'int'",)
+ViperTypeError("can't store to 'int'",)
+ViperTypeError("can't store 'None'",)
+ViperTypeError("can't store 'None'",)
ViperTypeError('must raise an object',)
ViperTypeError('unary op __pos__ not implemented',)
ViperTypeError('unary op __neg__ not implemented',)
ViperTypeError('unary op __invert__ not implemented',)
+ViperTypeError('binary op __contains__ not implemented',)
+NotImplementedError('native yield',)
+NotImplementedError('native yield from',)
+NotImplementedError('conversion to object',)
+NotImplementedError('casting',)
diff --git a/tests/micropython/viper_misc.py b/tests/micropython/viper_misc.py
index 8bf6cc638..021e03f2c 100644
--- a/tests/micropython/viper_misc.py
+++ b/tests/micropython/viper_misc.py
@@ -50,13 +50,6 @@ def viper_no_annotation(x, y):
return x * y
print(viper_no_annotation(4, 5))
-# unsigned ints
-@micropython.viper
-def viper_uint() -> uint:
- return uint(-1)
-import sys
-print(viper_uint() == (sys.maxsize << 1 | 1))
-
# a for loop
@micropython.viper
def viper_for(a:int, b:int) -> int:
diff --git a/tests/micropython/viper_misc.py.exp b/tests/micropython/viper_misc.py.exp
index 4800050d1..e4462771b 100644
--- a/tests/micropython/viper_misc.py.exp
+++ b/tests/micropython/viper_misc.py.exp
@@ -5,7 +5,6 @@ Ellipsis
6
7
20
-True
49994955
1 1
1 3
diff --git a/tests/micropython/viper_misc_intbig.py b/tests/micropython/viper_misc_intbig.py
new file mode 100644
index 000000000..e036435c7
--- /dev/null
+++ b/tests/micropython/viper_misc_intbig.py
@@ -0,0 +1,8 @@
+import micropython
+
+# unsigned ints
+@micropython.viper
+def viper_uint() -> uint:
+ return uint(-1)
+import sys
+print(viper_uint() == (sys.maxsize << 1 | 1))
diff --git a/tests/micropython/viper_misc_intbig.py.exp b/tests/micropython/viper_misc_intbig.py.exp
new file mode 100644
index 000000000..0ca95142b
--- /dev/null
+++ b/tests/micropython/viper_misc_intbig.py.exp
@@ -0,0 +1 @@
+True
diff --git a/tests/misc/non_compliant.py b/tests/misc/non_compliant.py
index e8ec74b5d..31074ab01 100644
--- a/tests/misc/non_compliant.py
+++ b/tests/misc/non_compliant.py
@@ -1,7 +1,12 @@
# tests for things that are not implemented, or have non-compliant behaviour
-import array
-import ustruct
+try:
+ import array
+ import ustruct
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
# when super can't find self
try:
@@ -124,3 +129,11 @@ try:
bytearray(4)[0:1] = [1, 2]
except NotImplementedError:
print('NotImplementedError')
+
+# can't assign attributes to a function
+def f():
+ pass
+try:
+ f.x = 1
+except AttributeError:
+ print('AttributeError')
diff --git a/tests/misc/non_compliant.py.exp b/tests/misc/non_compliant.py.exp
index caa5c4569..ba5590acc 100644
--- a/tests/misc/non_compliant.py.exp
+++ b/tests/misc/non_compliant.py.exp
@@ -19,3 +19,4 @@ NotImplementedError
b'\x01\x02'
b'\x01\x00'
NotImplementedError
+AttributeError
diff --git a/tests/misc/print_exception.py b/tests/misc/print_exception.py
index 9baac713e..b833a7981 100644
--- a/tests/misc/print_exception.py
+++ b/tests/misc/print_exception.py
@@ -1,8 +1,13 @@
+import sys
try:
- import uio as io
+ try:
+ import uio as io
+ except ImportError:
+ import io
except ImportError:
- import io
-import sys
+ print("SKIP")
+ sys.exit()
+
if hasattr(sys, 'print_exception'):
print_exception = sys.print_exception
else:
@@ -41,3 +46,13 @@ try:
except Exception as e:
print('caught')
print_exc(e)
+
+# Here we have a function with lots of bytecode generated for a single source-line, and
+# there is an error right at the end of the bytecode. It should report the correct line.
+def f():
+ f([1, 2], [1, 2], [1, 2], {1:1, 1:1, 1:1, 1:1, 1:1, 1:1, 1:X})
+ return 1
+try:
+ f()
+except Exception as e:
+ print_exc(e)
diff --git a/tests/misc/recursive_data.py b/tests/misc/recursive_data.py
index 0de93acb8..383018945 100644
--- a/tests/misc/recursive_data.py
+++ b/tests/misc/recursive_data.py
@@ -1,5 +1,10 @@
# This tests that printing recursive data structure doesn't lead to segfault.
-import uio as io
+try:
+ import uio as io
+except ImportError:
+ import sys
+ print("SKIP")
+ sys.exit()
l = [1, 2, 3, None]
l[-1] = l
diff --git a/tests/misc/recursive_iternext.py b/tests/misc/recursive_iternext.py
index 025fa425b..d90f17716 100644
--- a/tests/misc/recursive_iternext.py
+++ b/tests/misc/recursive_iternext.py
@@ -1,4 +1,14 @@
# This tests that recursion with iternext doesn't lead to segfault.
+try:
+ enumerate
+ filter
+ map
+ max
+ zip
+except:
+ import sys
+ print("SKIP")
+ sys.exit()
# We need to pick an N that is large enough to hit the recursion
# limit, but not too large that we run out of heap memory.
diff --git a/tests/pyb/adc.py b/tests/pyb/adc.py
index 6508d7e24..362ca326d 100644
--- a/tests/pyb/adc.py
+++ b/tests/pyb/adc.py
@@ -9,9 +9,12 @@ print(adc)
val = adc.read()
assert val < 500
+# timer for read_timed
+tim = pyb.Timer(5, freq=500)
+
# read into bytearray
buf = bytearray(50)
-adc.read_timed(buf, 500)
+adc.read_timed(buf, tim)
print(len(buf))
for i in buf:
assert i < 500
@@ -19,12 +22,12 @@ for i in buf:
# read into arrays with different element sizes
import array
ar = array.array('h', 25 * [0])
-adc.read_timed(ar, 500)
+adc.read_timed(ar, tim)
print(len(ar))
for i in buf:
assert i < 500
ar = array.array('i', 30 * [0])
-adc.read_timed(ar, 500)
+adc.read_timed(ar, tim)
print(len(ar))
for i in buf:
assert i < 500
diff --git a/tests/pyb/can.py b/tests/pyb/can.py
index 594d1d509..617eb7ccc 100644
--- a/tests/pyb/can.py
+++ b/tests/pyb/can.py
@@ -1,4 +1,10 @@
-from pyb import CAN
+try:
+ from pyb import CAN
+except ImportError:
+ print('SKIP')
+ import sys
+ sys.exit()
+
import pyb
# test we can correctly create by id or name
diff --git a/tests/pyb/dac.py b/tests/pyb/dac.py
index 884ec5829..942f30354 100644
--- a/tests/pyb/dac.py
+++ b/tests/pyb/dac.py
@@ -1,5 +1,10 @@
import pyb
+if not hasattr(pyb, 'DAC'):
+ print('SKIP')
+ import sys
+ sys.exit()
+
dac = pyb.DAC(1)
print(dac)
dac.noise(100)
diff --git a/tests/pyb/extint.py b/tests/pyb/extint.py
index a8ba484b1..ae98ccd5a 100644
--- a/tests/pyb/extint.py
+++ b/tests/pyb/extint.py
@@ -1,7 +1,7 @@
import pyb
# test basic functionality
-ext = pyb.ExtInt('X1', pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_DOWN, lambda l:print('line:', l))
+ext = pyb.ExtInt('Y1', pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_DOWN, lambda l:print('line:', l))
ext.disable()
ext.enable()
print(ext.line())
diff --git a/tests/pyb/extint.py.exp b/tests/pyb/extint.py.exp
index daed01c7f..1f9da9844 100644
--- a/tests/pyb/extint.py.exp
+++ b/tests/pyb/extint.py.exp
@@ -1,3 +1,3 @@
-0
-line: 0
-line: 0
+6
+line: 6
+line: 6
diff --git a/tests/pyb/pin.py b/tests/pyb/pin.py
index b3eb87b60..9b3788343 100644
--- a/tests/pyb/pin.py
+++ b/tests/pyb/pin.py
@@ -1,14 +1,14 @@
from pyb import Pin
-p = Pin('X1', Pin.IN)
+p = Pin('Y1', Pin.IN)
print(p)
print(p.name())
print(p.pin())
print(p.port())
-p = Pin('X1', Pin.IN, Pin.PULL_UP)
-p = Pin('X1', Pin.IN, pull=Pin.PULL_UP)
-p = Pin('X1', mode=Pin.IN, pull=Pin.PULL_UP)
+p = Pin('Y1', Pin.IN, Pin.PULL_UP)
+p = Pin('Y1', Pin.IN, pull=Pin.PULL_UP)
+p = Pin('Y1', mode=Pin.IN, pull=Pin.PULL_UP)
print(p)
print(p.value())
diff --git a/tests/pyb/pin.py.exp b/tests/pyb/pin.py.exp
index 599374600..f2f7038fd 100644
--- a/tests/pyb/pin.py.exp
+++ b/tests/pyb/pin.py.exp
@@ -1,10 +1,10 @@
-Pin(Pin.cpu.A0, mode=Pin.IN)
-A0
-0
-0
-Pin(Pin.cpu.A0, mode=Pin.IN, pull=Pin.PULL_UP)
+Pin(Pin.cpu.C6, mode=Pin.IN)
+C6
+6
+2
+Pin(Pin.cpu.C6, mode=Pin.IN, pull=Pin.PULL_UP)
1
-Pin(Pin.cpu.A0, mode=Pin.IN, pull=Pin.PULL_DOWN)
+Pin(Pin.cpu.C6, mode=Pin.IN, pull=Pin.PULL_DOWN)
0
0
1
diff --git a/tests/pyb/pyb1.py b/tests/pyb/pyb1.py
index 0087ec050..184acbdc4 100644
--- a/tests/pyb/pyb1.py
+++ b/tests/pyb/pyb1.py
@@ -27,16 +27,15 @@ print((pyb.millis() - start) // 5) # should print 3
pyb.disable_irq()
pyb.enable_irq()
-print(pyb.freq())
-
print(pyb.have_cdc())
pyb.hid((0, 0, 0, 0)) # won't do anything
-pyb.rng()
-
pyb.sync()
print(len(pyb.unique_id()))
pyb.wfi()
+
+pyb.fault_debug(True)
+pyb.fault_debug(False)
diff --git a/tests/pyb/pyb1.py.exp b/tests/pyb/pyb1.py.exp
index 84034d683..5816ea967 100644
--- a/tests/pyb/pyb1.py.exp
+++ b/tests/pyb/pyb1.py.exp
@@ -1,5 +1,4 @@
3
3
-(168000000, 168000000, 42000000, 84000000)
True
12
diff --git a/tests/pyb/pyb_f405.py b/tests/pyb/pyb_f405.py
new file mode 100644
index 000000000..3c81fe109
--- /dev/null
+++ b/tests/pyb/pyb_f405.py
@@ -0,0 +1,11 @@
+# test pyb module on F405 MCUs
+
+import os, pyb
+
+if not 'STM32F405' in os.uname().machine:
+ print('SKIP')
+ import sys
+ sys.exit()
+
+print(pyb.freq())
+print(type(pyb.rng()))
diff --git a/tests/pyb/pyb_f405.py.exp b/tests/pyb/pyb_f405.py.exp
new file mode 100644
index 000000000..a90aa0268
--- /dev/null
+++ b/tests/pyb/pyb_f405.py.exp
@@ -0,0 +1,2 @@
+(168000000, 168000000, 42000000, 84000000)
+<class 'int'>
diff --git a/tests/pyb/pyb_f411.py b/tests/pyb/pyb_f411.py
new file mode 100644
index 000000000..328653965
--- /dev/null
+++ b/tests/pyb/pyb_f411.py
@@ -0,0 +1,10 @@
+# test pyb module on F411 MCUs
+
+import os, pyb
+
+if not 'STM32F411' in os.uname().machine:
+ print('SKIP')
+ import sys
+ sys.exit()
+
+print(pyb.freq())
diff --git a/tests/pyb/pyb_f411.py.exp b/tests/pyb/pyb_f411.py.exp
new file mode 100644
index 000000000..79e0a1062
--- /dev/null
+++ b/tests/pyb/pyb_f411.py.exp
@@ -0,0 +1 @@
+(96000000, 96000000, 24000000, 48000000)
diff --git a/tests/pyb/rtc.py b/tests/pyb/rtc.py
index 300c95634..844526b4b 100644
--- a/tests/pyb/rtc.py
+++ b/tests/pyb/rtc.py
@@ -7,7 +7,7 @@ print(rtc)
# make sure that 1 second passes correctly
rtc.datetime((2014, 1, 1, 1, 0, 0, 0, 0))
-pyb.delay(1001)
+pyb.delay(1002)
print(rtc.datetime()[:7])
def set_and_print(datetime):
diff --git a/tests/run-tests b/tests/run-tests
index 91282667d..f24fc0961 100755
--- a/tests/run-tests
+++ b/tests/run-tests
@@ -23,7 +23,6 @@ MPYCROSS = os.getenv('MICROPY_MPYCROSS', '../mpy-cross/mpy-cross')
# Set PYTHONIOENCODING so that CPython will use utf-8 on systems which set another encoding in the locale
os.environ['PYTHONIOENCODING'] = 'utf-8'
-os.environ['MICROPYPATH'] = ''
def rm_f(fname):
if os.path.exists(fname):
@@ -50,15 +49,15 @@ def convert_regex_escapes(line):
return bytes(''.join(cs), 'utf8')
-def run_micropython(pyb, args, test_file):
- special_tests = ('micropython/meminfo.py', 'basics/bytes_compare3.py', 'thread/thread_exc2.py')
- is_special = False
+def run_micropython(pyb, args, test_file, is_special=False):
+ special_tests = ('micropython/meminfo.py', 'basics/bytes_compare3.py', 'basics/builtin_help.py', 'thread/thread_exc2.py')
if pyb is None:
# run on PC
if test_file.startswith(('cmdline/', 'feature_check/')) or test_file in special_tests:
# special handling for tests of the unix cmdline program
is_special = True
+ if is_special:
# check for any cmdline options needed for this test
args = [MICROPYTHON]
with open(test_file, 'rb') as f:
@@ -145,6 +144,10 @@ def run_micropython(pyb, args, test_file):
# canonical form for all ports/platforms is to use \n for end-of-line
output_mupy = output_mupy.replace(b'\r\n', b'\n')
+ # don't try to convert the output if we should skip this test
+ if output_mupy in (b'SKIP\n', b'CRASH'):
+ return output_mupy
+
if is_special or test_file in special_tests:
# convert parts of the output that are not stable across runs
with open(test_file + '.exp', 'rb') as f:
@@ -186,7 +189,12 @@ def run_micropython(pyb, args, test_file):
return output_mupy
-def run_tests(pyb, tests, args):
+
+def run_feature_check(pyb, args, base_path, test_file):
+ return run_micropython(pyb, args, base_path + "/feature_check/" + test_file, is_special=True)
+
+
+def run_tests(pyb, tests, args, base_path="."):
test_count = 0
testcase_count = 0
passed_count = 0
@@ -195,27 +203,45 @@ def run_tests(pyb, tests, args):
skip_tests = set()
skip_native = False
+ skip_int_big = False
skip_set_type = False
+ skip_async = False
+ skip_const = False
# Check if micropython.native is supported, and skip such tests if it's not
- native = run_micropython(pyb, args, 'feature_check/native_check.py')
+ native = run_feature_check(pyb, args, base_path, 'native_check.py')
if native == b'CRASH':
skip_native = True
+ # Check if arbitrary-precision integers are supported, and skip such tests if it's not
+ native = run_feature_check(pyb, args, base_path, 'int_big.py')
+ if native != b'1000000000000000000000000000000000000000000000\n':
+ skip_int_big = True
+
# Check if set type (and set literals) is supported, and skip such tests if it's not
- native = run_micropython(pyb, args, 'feature_check/set_check.py')
+ native = run_feature_check(pyb, args, base_path, 'set_check.py')
if native == b'CRASH':
skip_set_type = True
+ # Check if async/await keywords are supported, and skip such tests if it's not
+ native = run_feature_check(pyb, args, base_path, 'async_check.py')
+ if native == b'CRASH':
+ skip_async = True
+
+ # Check if const keyword (MicroPython extension) is supported, and skip such tests if it's not
+ native = run_feature_check(pyb, args, base_path, 'const.py')
+ if native == b'CRASH':
+ skip_const = True
+
# Check if emacs repl is supported, and skip such tests if it's not
- t = run_micropython(pyb, args, 'feature_check/repl_emacs_check.py')
+ t = run_feature_check(pyb, args, base_path, 'repl_emacs_check.py')
if not 'True' in str(t, 'ascii'):
skip_tests.add('cmdline/repl_emacs_keys.py')
- upy_byteorder = run_micropython(pyb, args, 'feature_check/byteorder.py')
- has_complex = run_micropython(pyb, args, 'feature_check/complex.py') == b'complex\n'
- has_coverage = run_micropython(pyb, args, 'feature_check/coverage.py') == b'coverage\n'
- cpy_byteorder = subprocess.check_output([CPYTHON3, 'feature_check/byteorder.py'])
+ upy_byteorder = run_feature_check(pyb, args, base_path, 'byteorder.py')
+ has_complex = run_feature_check(pyb, args, base_path, 'complex.py') == b'complex\n'
+ has_coverage = run_feature_check(pyb, args, base_path, 'coverage.py') == b'coverage\n'
+ cpy_byteorder = subprocess.check_output([CPYTHON3, base_path + '/feature_check/byteorder.py'])
skip_endian = (upy_byteorder != cpy_byteorder)
# Some tests shouldn't be run under Travis CI
@@ -228,6 +254,7 @@ def run_tests(pyb, tests, args):
if not has_complex:
skip_tests.add('float/complex1.py')
+ skip_tests.add('float/complex1_intbig.py')
skip_tests.add('float/int_big_float.py')
skip_tests.add('float/true_value.py')
skip_tests.add('float/types.py')
@@ -246,7 +273,7 @@ def run_tests(pyb, tests, args):
if pyb is not None:
skip_tests.add('basics/exception_chain.py') # warning is not printed
skip_tests.add('float/float_divmod.py') # tested by float/float_divmod_relaxed.py instead
- skip_tests.add('float/float2int_doubleprec.py') # requires double precision floating point to work
+ skip_tests.add('float/float2int_doubleprec_intbig.py') # requires double precision floating point to work
skip_tests.add('micropython/meminfo.py') # output is very different to PC output
skip_tests.add('extmod/machine_mem.py') # raw memory access not supported
@@ -264,11 +291,14 @@ def run_tests(pyb, tests, args):
skip_tests.add('extmod/urandom_basic.py') # requires urandom
skip_tests.add('extmod/urandom_extra.py') # requires urandom
elif args.target == 'esp8266':
- skip_tests.add('float/float2int.py') # requires at least fp32, there's float2int_fp30.py instead
+ skip_tests.add('float/float2int_intbig.py') # requires at least fp32, there's float2int_fp30_intbig.py instead
skip_tests.add('float/string_format.py') # requires at least fp32, there's string_format_fp30.py instead
skip_tests.add('float/bytes_construct.py') # requires fp32
skip_tests.add('float/bytearray_construct.py') # requires fp32
skip_tests.add('misc/rge_sm.py') # too large
+ elif args.target == 'minimal':
+ skip_tests.add('misc/rge_sm.py') # too large
+ skip_tests.add('micropython/opt_level.py') # don't assume line numbers are stored
# Some tests are known to fail on 64-bit machines
if pyb is None and platform.architecture()[0] == '64bit':
@@ -281,7 +311,7 @@ def run_tests(pyb, tests, args):
# Some tests are known to fail with native emitter
# Remove them from the below when they work
if args.emit == 'native':
- skip_tests.update({'basics/%s.py' % t for t in 'gen_yield_from gen_yield_from_close gen_yield_from_ducktype gen_yield_from_exc gen_yield_from_iter gen_yield_from_send gen_yield_from_stopped gen_yield_from_throw gen_yield_from_throw2 generator1 generator2 generator_args generator_close generator_closure generator_exc generator_return generator_send'.split()}) # require yield
+ skip_tests.update({'basics/%s.py' % t for t in 'gen_yield_from gen_yield_from_close gen_yield_from_ducktype gen_yield_from_exc gen_yield_from_iter gen_yield_from_send gen_yield_from_stopped gen_yield_from_throw gen_yield_from_throw2 gen_yield_from_throw3 generator1 generator2 generator_args generator_close generator_closure generator_exc generator_return generator_send'.split()}) # require yield
skip_tests.update({'basics/%s.py' % t for t in 'bytes_gen class_store_class globals_del string_join'.split()}) # require yield
skip_tests.update({'basics/async_%s.py' % t for t in 'def await await2 for for2 with with2'.split()}) # require yield
skip_tests.update({'basics/%s.py' % t for t in 'try_reraise try_reraise2'.split()}) # require raise_varargs
@@ -303,6 +333,8 @@ def run_tests(pyb, tests, args):
skip_tests.add('misc/print_exception.py') # because native doesn't have proper traceback info
skip_tests.add('misc/sys_exc_info.py') # sys.exc_info() is not supported for native
skip_tests.add('micropython/heapalloc_traceback.py') # because native doesn't have proper traceback info
+ skip_tests.add('micropython/heapalloc_iter.py') # requires generators
+ skip_tests.add('micropython/schedule.py') # native code doesn't check pending events
for test_file in tests:
test_file = test_file.replace('\\', '/')
@@ -310,12 +342,18 @@ def run_tests(pyb, tests, args):
test_name = os.path.splitext(test_basename)[0]
is_native = test_name.startswith("native_") or test_name.startswith("viper_")
is_endian = test_name.endswith("_endian")
- is_set_type = test_name.startswith("set_")
+ is_int_big = test_name.startswith("int_big") or test_name.endswith("_intbig")
+ is_set_type = test_name.startswith("set_") or test_name.startswith("frozenset")
+ is_async = test_name.startswith("async_")
+ is_const = test_name.startswith("const")
skip_it = test_file in skip_tests
skip_it |= skip_native and is_native
skip_it |= skip_endian and is_endian
+ skip_it |= skip_int_big and is_int_big
skip_it |= skip_set_type and is_set_type
+ skip_it |= skip_async and is_async
+ skip_it |= skip_const and is_const
if skip_it:
print("skip ", test_file)
@@ -396,10 +434,11 @@ def main():
cmd_parser.add_argument('--emit', default='bytecode', help='MicroPython emitter to use (bytecode or native)')
cmd_parser.add_argument('--heapsize', help='heapsize to use (use default if not specified)')
cmd_parser.add_argument('--via-mpy', action='store_true', help='compile .py files to .mpy first')
+ cmd_parser.add_argument('--keep-path', action='store_true', help='do not clear MICROPYPATH when running tests')
cmd_parser.add_argument('files', nargs='*', help='input test files')
args = cmd_parser.parse_args()
- EXTERNAL_TARGETS = ('pyboard', 'wipy', 'esp8266')
+ EXTERNAL_TARGETS = ('pyboard', 'wipy', 'esp8266', 'minimal')
if args.target in EXTERNAL_TARGETS:
import pyboard
pyb = pyboard.Pyboard(args.device, args.baudrate, args.user, args.password)
@@ -414,7 +453,7 @@ def main():
if args.target == 'pyboard':
# run pyboard tests
test_dirs = ('basics', 'micropython', 'float', 'misc', 'stress', 'extmod', 'pyb', 'pybnative', 'inlineasm')
- elif args.target == 'esp8266':
+ elif args.target in ('esp8266', 'minimal'):
test_dirs = ('basics', 'micropython', 'float', 'misc', 'extmod')
elif args.target == 'wipy':
# run WiPy tests
@@ -430,7 +469,18 @@ def main():
# tests explicitly given
tests = args.files
- if not run_tests(pyb, tests, args):
+ if not args.keep_path:
+ # clear search path to make sure tests use only builtin modules
+ os.environ['MICROPYPATH'] = ''
+
+ # Even if we run completely different tests in a different directory,
+ # we need to access feature_check's from the same directory as the
+ # run-tests script itself.
+ base_path = os.path.dirname(sys.argv[0]) or "."
+ res = run_tests(pyb, tests, args, base_path)
+ if pyb:
+ pyb.close()
+ if not res:
sys.exit(1)
if __name__ == "__main__":
diff --git a/tests/thread/stress_create.py b/tests/thread/stress_create.py
new file mode 100644
index 000000000..2399746cc
--- /dev/null
+++ b/tests/thread/stress_create.py
@@ -0,0 +1,22 @@
+# stress test for creating many threads
+
+try:
+ import utime as time
+except ImportError:
+ import time
+import _thread
+
+def thread_entry(n):
+ pass
+
+thread_num = 0
+while thread_num < 500:
+ try:
+ _thread.start_new_thread(thread_entry, (thread_num,))
+ thread_num += 1
+ except MemoryError:
+ pass
+
+# wait for the last threads to terminate
+time.sleep(1)
+print('done')
diff --git a/tests/thread/stress_heap.py b/tests/thread/stress_heap.py
index ac3ebe049..5482a9ac6 100644
--- a/tests/thread/stress_heap.py
+++ b/tests/thread/stress_heap.py
@@ -3,6 +3,10 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+try:
+ import utime as time
+except ImportError:
+ import time
import _thread
def last(l):
@@ -37,6 +41,6 @@ n_finished = 0
for i in range(n_thread):
_thread.start_new_thread(thread_entry, (10000,))
-# busy wait for threads to finish
+# wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(1)
diff --git a/tests/thread/thread_exc2.py.exp b/tests/thread/thread_exc2.py.exp
index 584bfab4d..cc7a20aa2 100644
--- a/tests/thread/thread_exc2.py.exp
+++ b/tests/thread/thread_exc2.py.exp
@@ -1,5 +1,5 @@
Unhandled exception in thread started by <function thread_entry at 0x\[0-9a-f\]\+>
Traceback (most recent call last):
- File "thread/thread_exc2.py", line 6, in thread_entry
+ File \.\+, line 6, in thread_entry
ValueError:
done
diff --git a/tests/thread/thread_lock4.py b/tests/thread/thread_lock4.py
index d77aa24ee..2f9d42d6b 100644
--- a/tests/thread/thread_lock4.py
+++ b/tests/thread/thread_lock4.py
@@ -2,6 +2,10 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+try:
+ import utime as time
+except ImportError:
+ import time
import _thread
def fac(n):
@@ -39,6 +43,7 @@ while True:
with jobs_lock:
if len(output) == n_jobs:
break
+ time.sleep(1)
# sort and print the results
output.sort(key=lambda x: x[0])
diff --git a/tests/thread/thread_qstr1.py b/tests/thread/thread_qstr1.py
index c0256316e..f4136d964 100644
--- a/tests/thread/thread_qstr1.py
+++ b/tests/thread/thread_qstr1.py
@@ -2,6 +2,10 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+try:
+ import utime as time
+except ImportError:
+ import time
import _thread
# function to check the interned string
@@ -28,8 +32,8 @@ n_qstr_per_thread = 100 # make 1000 for a more stressful test (uses more heap)
for i in range(n_thread):
_thread.start_new_thread(th, (i * n_qstr_per_thread, n_qstr_per_thread))
-# busy wait for threads to finish
+# wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(1)
print('pass')
diff --git a/tests/thread/thread_stacksize1.py b/tests/thread/thread_stacksize1.py
index e62899631..62b6e5e40 100644
--- a/tests/thread/thread_stacksize1.py
+++ b/tests/thread/thread_stacksize1.py
@@ -38,6 +38,9 @@ _thread.stack_size(sz)
for i in range(n_thread):
_thread.start_new_thread(thread_entry, ())
+# reset stack size to default (for subsequent scripts on baremetal)
+_thread.stack_size()
+
# busy wait for threads to finish
while n_finished < n_thread:
pass
diff --git a/tests/unix/extra_coverage.py b/tests/unix/extra_coverage.py
index f2b40282b..870e7d5f2 100644
--- a/tests/unix/extra_coverage.py
+++ b/tests/unix/extra_coverage.py
@@ -5,15 +5,52 @@ except NameError:
import sys
sys.exit()
+import uerrno
+import uio
+
data = extra_coverage()
# test hashing of str/bytes that have an invalid hash
-print(data)
+print(data[0], data[1])
print(hash(data[0]))
print(hash(data[1]))
print(hash(bytes(data[0], 'utf8')))
print(hash(str(data[1], 'utf8')))
+# test streams
+stream = data[2] # has set_error and set_buf. Write always returns error
+stream.set_error(uerrno.EAGAIN) # non-blocking error
+print(stream.read()) # read all encounters non-blocking error
+print(stream.read(1)) # read 1 byte encounters non-blocking error
+print(stream.readline()) # readline encounters non-blocking error
+print(stream.readinto(bytearray(10))) # readinto encounters non-blocking error
+print(stream.write(b'1')) # write encounters non-blocking error
+print(stream.write1(b'1')) # write1 encounters non-blocking error
+stream.set_buf(b'123')
+print(stream.read(4)) # read encounters non-blocking error after successful reads
+stream.set_buf(b'123')
+print(stream.read1(4)) # read1 encounters non-blocking error after successful reads
+stream.set_buf(b'123')
+print(stream.readline(4)) # readline encounters non-blocking error after successful reads
+try:
+ print(stream.ioctl(0, 0)) # ioctl encounters non-blocking error; raises OSError
+except OSError:
+ print('OSError')
+stream.set_error(0)
+print(stream.ioctl(0, bytearray(10))) # successful ioctl call
+
+stream2 = data[3] # is textio and sets .write = NULL
+try:
+ print(stream2.write(b'1')) # attempt to call NULL implementation
+except OSError:
+ print('OSError')
+print(stream2.read(1)) # read 1 byte encounters non-blocking error with textio stream
+
+# test BufferedWriter with stream errors
+stream.set_error(uerrno.EAGAIN)
+buf = uio.BufferedWriter(stream, 8)
+print(buf.write(bytearray(16)))
+
# test basic import of frozen scripts
import frzstr1
import frzmpy1
@@ -29,3 +66,9 @@ from frzstr_pkg2.mod import Foo
print(Foo.x)
from frzmpy_pkg2.mod import Foo
print(Foo.x)
+
+# test raising exception in frozen script
+try:
+ import frzmpy2
+except ZeroDivisionError:
+ print('ZeroDivisionError')
diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp
index d3d725211..416993887 100644
--- a/tests/unix/extra_coverage.py.exp
+++ b/tests/unix/extra_coverage.py.exp
@@ -43,11 +43,39 @@ Warning: test
?
+1e+00
+1e+00
-('0123456789', b'0123456789')
+# binary
+122
+456
+# scheduler
+sched(0)=1
+sched(1)=1
+sched(2)=1
+sched(3)=1
+sched(4)=0
+unlocked
+3
+2
+1
+0
+0123456789 b'0123456789'
7300
7300
7300
7300
+None
+None
+None
+None
+None
+None
+b'123'
+b'123'
+b'123'
+OSError
+0
+OSError
+None
+None
frzstr1
frzmpy1
frzstr_pkg1.__init__
@@ -58,3 +86,4 @@ frzstr_pkg2.mod
1
frzmpy_pkg2.mod
1
+ZeroDivisionError