diff options
Diffstat (limited to 'tests')
47 files changed, 498 insertions, 58 deletions
diff --git a/tests/basics/bytes.py b/tests/basics/bytes.py index d3da15c8e..1d97e6b16 100644 --- a/tests/basics/bytes.py +++ b/tests/basics/bytes.py @@ -8,6 +8,9 @@ print(b'\u1234') print(bytes()) print(bytes(b'abc')) +# make sure empty bytes is converted correctly +print(str(bytes(), 'utf-8')) + a = b"123" print(a) print(str(a)) diff --git a/tests/basics/class_inplace_op.py b/tests/basics/class_inplace_op.py new file mode 100644 index 000000000..62aad8c7c --- /dev/null +++ b/tests/basics/class_inplace_op.py @@ -0,0 +1,47 @@ +# Case 1: Immutable object (e.g. number-like) +# __iadd__ should not be defined, will be emulated using __add__ + +class A: + + def __init__(self, v): + self.v = v + + def __add__(self, o): + return A(self.v + o.v) + + def __repr__(self): + return "A(%s)" % self.v + +a = A(5) +b = a +a += A(3) +print(a) +# Should be original a's value, i.e. A(5) +print(b) + +# Case 2: Mutable object (e.g. list-like) +# __iadd__ should be defined + +class L: + + def __init__(self, v): + self.v = v + + def __add__(self, o): + # Should not be caled in this test + print("L.__add__") + return L(self.v + o.v) + + def __iadd__(self, o): + self.v += o.v + return self + + def __repr__(self): + return "L(%s)" % self.v + +c = L([1, 2]) +d = c +c += L([3, 4]) +print(c) +# Should be updated c's value, i.e. L([1, 2, 3, 4]) +print(d) diff --git a/tests/basics/class_new.py b/tests/basics/class_new.py index 9a7072ad0..1f6a86c64 100644 --- a/tests/basics/class_new.py +++ b/tests/basics/class_new.py @@ -5,13 +5,14 @@ try: except AttributeError: print("SKIP") raise SystemExit + class A: def __new__(cls): print("A.__new__") return super(cls, A).__new__(cls) def __init__(self): - pass + print("A.__init__") def meth(self): print('A.meth') @@ -33,7 +34,33 @@ a.meth() a = a.__new__(A) a.meth() +# __new__ returns not an instance of the class (None here), __init__ +# should not be called + class B: def __new__(self, v1, v2): - None -B(1, 2) + print("B.__new__", v1, v2) + + def __init__(self, v1, v2): + # Should not be called in this test + print("B.__init__", v1, v2) + +print("B inst:", B(1, 2)) + + +# Variation of the above, __new__ returns an instance of another class, +# __init__ should not be called + +class Dummy: pass + +class C: + def __new__(cls): + print("C.__new__") + return Dummy() + + def __init__(self): + # Should not be called in this test + print("C.__init__") + +c = C() +print(isinstance(c, Dummy)) diff --git a/tests/basics/class_notimpl.py b/tests/basics/class_notimpl.py new file mode 100644 index 000000000..7fd8166f9 --- /dev/null +++ b/tests/basics/class_notimpl.py @@ -0,0 +1,50 @@ +# Test that returning of NotImplemented from binary op methods leads to +# TypeError. +try: + NotImplemented +except NameError: + print("SKIP") + raise SystemExit + +class C: + def __init__(self, value): + self.value = value + + def __str__(self): + return "C(%s)" % self.value + + def __add__(self, rhs): + print(self, '+', rhs) + return NotImplemented + + def __sub__(self, rhs): + print(self, '-', rhs) + return NotImplemented + + def __lt__(self, rhs): + print(self, '<', rhs) + return NotImplemented + + def __neg__(self): + print('-', self) + return NotImplemented + +c = C(0) + +try: + c + 1 +except TypeError: + print("TypeError") + +try: + c - 2 +except TypeError: + print("TypeError") + +try: + c < 1 +except TypeError: + print("TypeError") + +# NotImplemented isn't handled specially in unary methods +print(-c) diff --git a/tests/basics/class_reverse_op.py b/tests/basics/class_reverse_op.py new file mode 100644 index 000000000..d41c55c9d --- /dev/null +++ b/tests/basics/class_reverse_op.py @@ -0,0 +1,18 @@ +class A: + + def __init__(self, v): + self.v = v + + def __add__(self, o): + if isinstance(o, A): + return A(self.v + o.v) + return A(self.v + o) + + def __radd__(self, o): + return A(self.v + o) + + def __repr__(self): + return "A(%s)" % self.v + +print(A(3) + 1) +print(2 + A(5)) diff --git a/tests/basics/containment.py b/tests/basics/containment.py index bae366113..4c94a9bae 100644 --- a/tests/basics/containment.py +++ b/tests/basics/containment.py @@ -16,6 +16,17 @@ for needle in [haystack[:i+1] for i in range(len(haystack))]: print(haystack, "in", needle, "::", haystack in needle) print(haystack, "not in", needle, "::", haystack not in needle) +# containment of bytes/ints in bytes +print(b'' in b'123') +print(b'0' in b'123', b'1' in b'123') +print(48 in b'123', 49 in b'123') + +# containment of int in str is an error +try: + 1 in '123' +except TypeError: + print('TypeError') + # until here, the tests would work without the 'second attempt' iteration thing. for i in 1, 2: diff --git a/tests/basics/list_compare.py b/tests/basics/list_compare.py index eea881424..fd656c7f1 100644 --- a/tests/basics/list_compare.py +++ b/tests/basics/list_compare.py @@ -48,3 +48,13 @@ print([1] <= [1, 0]) print([1] <= [1, -1]) print([1, 0] <= [1]) print([1, -1] <= [1]) + + +print([] == {}) +print([] != {}) +print([1] == (1,)) + +try: + print([] < {}) +except TypeError: + print("TypeError") diff --git a/tests/basics/object_new.py b/tests/basics/object_new.py index a9c9482cb..1bf7bc0ec 100644 --- a/tests/basics/object_new.py +++ b/tests/basics/object_new.py @@ -12,6 +12,11 @@ except AttributeError: class Foo: + def __new__(cls): + # Should not be called in this test + print("in __new__") + raise RuntimeError + def __init__(self): print("in __init__") self.attr = "something" @@ -19,12 +24,13 @@ class Foo: o = object.__new__(Foo) #print(o) -print(hasattr(o, "attr")) -print(isinstance(o, Foo)) +print("Result of __new__ has .attr:", hasattr(o, "attr")) +print("Result of __new__ is already a Foo:", isinstance(o, Foo)) + o.__init__() #print(dir(o)) -print(hasattr(o, "attr")) -print(o.attr) +print("After __init__ has .attr:", hasattr(o, "attr")) +print(".attr:", o.attr) # should only be able to call __new__ on user types try: diff --git a/tests/basics/set_binop.py b/tests/basics/set_binop.py index 7848920b6..bc76533b1 100644 --- a/tests/basics/set_binop.py +++ b/tests/basics/set_binop.py @@ -47,6 +47,18 @@ s1 = s2 = set('abc') s1 -= set('ad') print(s1 is s2, len(s1)) +# RHS must be a set +try: + print(set('12') >= '1') +except TypeError: + print('TypeError') + +# RHS must be a set +try: + print(set('12') <= '123') +except TypeError: + print('TypeError') + # unsupported operator try: set('abc') * 2 diff --git a/tests/basics/set_remove.py b/tests/basics/set_remove.py index 5627516c4..072723911 100644 --- a/tests/basics/set_remove.py +++ b/tests/basics/set_remove.py @@ -4,8 +4,8 @@ print(s.remove(1)) print(list(s)) try: print(s.remove(1), "!!!") -except KeyError: - pass +except KeyError as er: + print('KeyError', er.args[0]) else: print("failed to raise KeyError") diff --git a/tests/basics/string_endswith.py b/tests/basics/string_endswith.py index 3e8fba925..683562d10 100644 --- a/tests/basics/string_endswith.py +++ b/tests/basics/string_endswith.py @@ -10,3 +10,8 @@ print("foobar".endswith("foobarbaz")) #print("1foo".startswith("1foo", 1)) #print("1fo".startswith("foo", 1)) #print("1fo".startswith("foo", 10)) + +try: + "foobar".endswith(1) +except TypeError: + print("TypeError") diff --git a/tests/basics/string_endswith_upy.py b/tests/basics/string_endswith_upy.py new file mode 100644 index 000000000..06a4e71d2 --- /dev/null +++ b/tests/basics/string_endswith_upy.py @@ -0,0 +1,6 @@ +# MicroPython doesn't support tuple argument + +try: + "foobar".endswith(("bar", "sth")) +except TypeError: + print("TypeError") diff --git a/tests/basics/string_endswith_upy.py.exp b/tests/basics/string_endswith_upy.py.exp new file mode 100644 index 000000000..6002b71c5 --- /dev/null +++ b/tests/basics/string_endswith_upy.py.exp @@ -0,0 +1 @@ +TypeError diff --git a/tests/basics/string_startswith.py b/tests/basics/string_startswith.py index 5cf730c03..e63ae3c18 100644 --- a/tests/basics/string_startswith.py +++ b/tests/basics/string_startswith.py @@ -9,3 +9,8 @@ print("1foo".startswith("foo", 1)) print("1foo".startswith("1foo", 1)) print("1fo".startswith("foo", 1)) print("1fo".startswith("foo", 10)) + +try: + "foobar".startswith(1) +except TypeError: + print("TypeError") diff --git a/tests/basics/string_startswith_upy.py b/tests/basics/string_startswith_upy.py new file mode 100644 index 000000000..9ea1796c2 --- /dev/null +++ b/tests/basics/string_startswith_upy.py @@ -0,0 +1,6 @@ +# MicroPython doesn't support tuple argument + +try: + "foobar".startswith(("foo", "sth")) +except TypeError: + print("TypeError") diff --git a/tests/basics/string_startswith_upy.py.exp b/tests/basics/string_startswith_upy.py.exp new file mode 100644 index 000000000..6002b71c5 --- /dev/null +++ b/tests/basics/string_startswith_upy.py.exp @@ -0,0 +1 @@ +TypeError diff --git a/tests/basics/string_strip.py b/tests/basics/string_strip.py index 5d99a78e5..971a4aae5 100644 --- a/tests/basics/string_strip.py +++ b/tests/basics/string_strip.py @@ -32,6 +32,13 @@ print("a ".strip()) print("a ".lstrip()) print("a ".rstrip()) +# \0 used to give a problem + +print("\0abc\0".strip()) +print("\0abc\0".lstrip()) +print("\0abc\0".rstrip()) +print("\0abc\0".strip("\0")) + # Test that stripping unstrippable string returns original object s = "abc" print(id(s.strip()) == id(s)) diff --git a/tests/basics/struct1.py b/tests/basics/struct1.py index a442beb1e..db34342a1 100644 --- a/tests/basics/struct1.py +++ b/tests/basics/struct1.py @@ -39,6 +39,12 @@ print(v == (10, 100, 200, 300)) # network byte order print(struct.pack('!i', 123)) +# check that we get an error if the buffer is too small +try: + struct.unpack('I', b'\x00\x00\x00') +except: + print('struct.error') + # first arg must be a string try: struct.pack(1, 2) @@ -63,6 +69,12 @@ print(buf) struct.pack_into('<bbb', buf, -6, 0x44, 0x45, 0x46) print(buf) +# check that we get an error if the buffer is too small +try: + struct.pack_into('I', bytearray(1), 0, 0) +except: + print('struct.error') + try: struct.pack_into('<bbb', buf, 7, 0x41, 0x42, 0x43) except: diff --git a/tests/basics/struct1_intbig.py b/tests/basics/struct1_intbig.py index b1fec527e..380293f36 100644 --- a/tests/basics/struct1_intbig.py +++ b/tests/basics/struct1_intbig.py @@ -12,6 +12,8 @@ print(struct.pack("<I", 2**32 - 1)) print(struct.pack("<I", 0xffffffff)) # long long ints +print(struct.pack("<Q", 1)) +print(struct.pack(">Q", 1)) print(struct.pack("<Q", 2**64 - 1)) print(struct.pack(">Q", 2**64 - 1)) print(struct.pack("<Q", 0xffffffffffffffff)) diff --git a/tests/basics/struct2.py b/tests/basics/struct2.py index d8234d0d3..ceb067776 100644 --- a/tests/basics/struct2.py +++ b/tests/basics/struct2.py @@ -25,6 +25,16 @@ print(struct.calcsize('0s1s0H2H')) print(struct.unpack('<0s1s0H2H', b'01234')) print(struct.pack('<0s1s0H2H', b'abc', b'abc', 258, 515)) +# check that we get an error if the buffer is too small +try: + struct.unpack('2H', b'\x00\x00') +except: + print('Exception') +try: + struct.pack_into('2I', bytearray(4), 0, 0) +except: + print('Exception') + # check that unknown types raise an exception try: struct.unpack('z', b'1') @@ -40,3 +50,30 @@ try: struct.calcsize('0z') except: print('Exception') + +# check that a count without a type specifier raises an exception + +try: + struct.calcsize('1') +except: + print('Exception') + +try: + struct.pack('1') +except: + print('Exception') + +try: + struct.pack_into('1', bytearray(4), 0, 'xx') +except: + print('Exception') + +try: + struct.unpack('1', 'xx') +except: + print('Exception') + +try: + struct.unpack_from('1', 'xx') +except: + print('Exception') diff --git a/tests/basics/struct_micropython.py b/tests/basics/struct_micropython.py index 4b9dfe137..f203a4666 100644 --- a/tests/basics/struct_micropython.py +++ b/tests/basics/struct_micropython.py @@ -18,6 +18,9 @@ s = struct.pack("<O", o) o2 = struct.unpack("<O", s) print(o is o2[0]) +# pack can accept less arguments than required for the format spec +print(struct.pack('<2I', 1)) + # 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 diff --git a/tests/basics/struct_micropython.py.exp b/tests/basics/struct_micropython.py.exp index 0ca95142b..55b7b6623 100644 --- a/tests/basics/struct_micropython.py.exp +++ b/tests/basics/struct_micropython.py.exp @@ -1 +1,2 @@ True +b'\x01\x00\x00\x00\x00\x00\x00\x00' diff --git a/tests/basics/tuple_compare.py b/tests/basics/tuple_compare.py index ad813f702..9558eb1db 100644 --- a/tests/basics/tuple_compare.py +++ b/tests/basics/tuple_compare.py @@ -53,3 +53,13 @@ print((10, 0) > (1, 1)) print((10, 0) < (1, 1)) print((0, 0, 10, 0) > (0, 0, 1, 1)) print((0, 0, 10, 0) < (0, 0, 1, 1)) + + +print(() == {}) +print(() != {}) +print((1,) == [1]) + +try: + print(() < {}) +except TypeError: + print("TypeError") diff --git a/tests/basics/tuple_mult.py b/tests/basics/tuple_mult.py index b128b2968..cac95185a 100644 --- a/tests/basics/tuple_mult.py +++ b/tests/basics/tuple_mult.py @@ -11,6 +11,11 @@ a = (1, 2, 3) c = a * 3 print(a, c) +# inplace multiplication +a = (1, 2) +a *= 2 +print(a) + # unsupported type on RHS try: () * None diff --git a/tests/cmdline/cmd_showbc.py.exp b/tests/cmdline/cmd_showbc.py.exp index 1e015eb03..09fbff6fa 100644 --- a/tests/cmdline/cmd_showbc.py.exp +++ b/tests/cmdline/cmd_showbc.py.exp @@ -43,9 +43,9 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): bc=\\d\+ line=126 00 LOAD_CONST_NONE 01 LOAD_CONST_FALSE -02 BINARY_OP 5 __add__ +02 BINARY_OP 28 __add__ 03 LOAD_CONST_TRUE -04 BINARY_OP 5 __add__ +04 BINARY_OP 28 __add__ 05 STORE_FAST 0 06 LOAD_CONST_SMALL_INT 0 07 STORE_FAST 0 @@ -84,34 +84,34 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): \\d\+ STORE_FAST 7 \\d\+ LOAD_FAST 0 \\d\+ LOAD_DEREF 14 -\\d\+ BINARY_OP 5 __add__ +\\d\+ BINARY_OP 28 __add__ \\d\+ STORE_FAST 8 \\d\+ LOAD_FAST 0 -\\d\+ UNARY_OP 4 +\\d\+ UNARY_OP 1 \\d\+ STORE_FAST 9 \\d\+ LOAD_FAST 0 -\\d\+ UNARY_OP 6 +\\d\+ UNARY_OP 3 \\d\+ STORE_FAST 10 \\d\+ LOAD_FAST 0 \\d\+ LOAD_DEREF 14 \\d\+ DUP_TOP \\d\+ ROT_THREE -\\d\+ BINARY_OP 27 __eq__ +\\d\+ BINARY_OP 2 __eq__ \\d\+ JUMP_IF_FALSE_OR_POP \\d\+ \\d\+ LOAD_FAST 1 -\\d\+ BINARY_OP 27 __eq__ +\\d\+ BINARY_OP 2 __eq__ \\d\+ JUMP \\d\+ \\d\+ ROT_TWO \\d\+ POP_TOP \\d\+ STORE_FAST 10 \\d\+ LOAD_FAST 0 \\d\+ LOAD_DEREF 14 -\\d\+ BINARY_OP 27 __eq__ +\\d\+ BINARY_OP 2 __eq__ \\d\+ JUMP_IF_FALSE_OR_POP \\d\+ \\d\+ LOAD_DEREF 14 \\d\+ LOAD_FAST 1 -\\d\+ BINARY_OP 27 __eq__ -\\d\+ UNARY_OP 6 +\\d\+ BINARY_OP 2 __eq__ +\\d\+ UNARY_OP 3 \\d\+ STORE_FAST 10 \\d\+ LOAD_DEREF 14 \\d\+ LOAD_ATTR c (cache=0) @@ -132,7 +132,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): \\d\+ DUP_TOP_TWO \\d\+ LOAD_SUBSCR \\d\+ LOAD_FAST 12 -\\d\+ BINARY_OP 18 __iadd__ +\\d\+ BINARY_OP 16 __iadd__ \\d\+ ROT_THREE \\d\+ STORE_SUBSCR \\d\+ LOAD_DEREF 14 @@ -369,7 +369,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): 42 STORE_FAST_N 19 44 LOAD_FAST 9 45 LOAD_FAST_N 19 -47 BINARY_OP 5 __add__ +47 BINARY_OP 28 __add__ 48 POP_TOP 49 LOAD_CONST_NONE 50 RETURN_VALUE @@ -521,7 +521,7 @@ arg names: * bc=\\d\+ line=113 00 LOAD_DEREF 0 02 LOAD_CONST_SMALL_INT 1 -03 BINARY_OP 5 __add__ +03 BINARY_OP 28 __add__ 04 STORE_FAST 1 05 LOAD_CONST_SMALL_INT 1 06 STORE_DEREF 0 @@ -540,7 +540,7 @@ arg names: * b bc=\\d\+ line=139 00 LOAD_FAST 1 01 LOAD_DEREF 0 -03 BINARY_OP 5 __add__ +03 BINARY_OP 28 __add__ 04 RETURN_VALUE mem: total=\\d\+, current=\\d\+, peak=\\d\+ stack: \\d\+ out of \\d\+ diff --git a/tests/cpydiff/core_locals.py b/tests/cpydiff/core_locals.py new file mode 100644 index 000000000..0240e5a1a --- /dev/null +++ b/tests/cpydiff/core_locals.py @@ -0,0 +1,11 @@ +""" +categories: Core,Runtime +description: Local variables aren't included in locals() result +cause: MicroPython doesn't maintain symbolic local environment, it is optimized to an array of slots. Thus, local variables can't be accessed by a name. +workaround: Unknown +""" +def test(): + val = 2 + print(locals()) + +test() diff --git a/tests/cpydiff/core_locals_eval.py b/tests/cpydiff/core_locals_eval.py new file mode 100644 index 000000000..8416e3b06 --- /dev/null +++ b/tests/cpydiff/core_locals_eval.py @@ -0,0 +1,14 @@ +""" +categories: Core,Runtime +description: Code running in eval() function doesn't have access to local variables +cause: MicroPython doesn't maintain symbolic local environment, it is optimized to an array of slots. Thus, local variables can't be accessed by a name. Effectively, ``eval(expr)`` in MicroPython is equivalent to ``eval(expr, globals(), globals())``. +workaround: Unknown +""" +val = 1 + +def test(): + val = 2 + print(val) + eval("print(val)") + +test() diff --git a/tests/extmod/ubinascii_a2b_base64.py b/tests/extmod/ubinascii_a2b_base64.py index b35f26591..05a3169f3 100644 --- a/tests/extmod/ubinascii_a2b_base64.py +++ b/tests/extmod/ubinascii_a2b_base64.py @@ -21,6 +21,13 @@ print(binascii.a2b_base64(b'f4D/')) print(binascii.a2b_base64(b'f4D+')) # convert '+' print(binascii.a2b_base64(b'MTIzNEFCQ0RhYmNk')) +# Ignore invalid characters and pad sequences +print(binascii.a2b_base64(b'Zm9v\n')) +print(binascii.a2b_base64(b'Zm\x009v\n')) +print(binascii.a2b_base64(b'Zm9v==')) +print(binascii.a2b_base64(b'Zm9v===')) +print(binascii.a2b_base64(b'Zm9v===YmFy')) + try: print(binascii.a2b_base64(b'abc')) except ValueError: diff --git a/tests/extmod/ure_stack_overflow.py b/tests/extmod/ure_stack_overflow.py new file mode 100644 index 000000000..d3ce0c5a7 --- /dev/null +++ b/tests/extmod/ure_stack_overflow.py @@ -0,0 +1,13 @@ +try: + import ure as re +except ImportError: + try: + import re + except ImportError: + print("SKIP") + raise SystemExit + +try: + re.match("(a*)*", "aaa") +except RuntimeError: + print("RuntimeError") diff --git a/tests/extmod/ure_stack_overflow.py.exp b/tests/extmod/ure_stack_overflow.py.exp new file mode 100644 index 000000000..8a2b9bfdd --- /dev/null +++ b/tests/extmod/ure_stack_overflow.py.exp @@ -0,0 +1 @@ +RuntimeError diff --git a/tests/feature_check/reverse_ops.py b/tests/feature_check/reverse_ops.py new file mode 100644 index 000000000..668748bc5 --- /dev/null +++ b/tests/feature_check/reverse_ops.py @@ -0,0 +1,9 @@ +class Foo: + + def __radd__(self, other): + pass + +try: + 5 + Foo() +except TypeError: + print("TypeError") diff --git a/tests/feature_check/reverse_ops.py.exp b/tests/feature_check/reverse_ops.py.exp new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/feature_check/reverse_ops.py.exp diff --git a/tests/float/complex1.py b/tests/float/complex1.py index a6038de04..854410545 100644 --- a/tests/float/complex1.py +++ b/tests/float/complex1.py @@ -37,6 +37,11 @@ ans = 1j ** 2.5j; print("%.5g %.5g" % (ans.real, ans.imag)) print(1j == 1) print(1j == 1j) +# comparison of nan is special +nan = float('nan') * 1j +print(nan == 1j) +print(nan == nan) + # builtin abs print(abs(1j)) print("%.5g" % abs(1j + 2)) @@ -48,6 +53,10 @@ print(type(hash(1j))) # float on lhs should delegate to complex print(1.2 + 3j) +# negative base and fractional power should create a complex +ans = (-1) ** 2.3; print("%.5g %.5g" % (ans.real, ans.imag)) +ans = (-1.2) ** -3.4; print("%.5g %.5g" % (ans.real, ans.imag)) + # check printing of inf/nan print(float('nan') * 1j) print(float('inf') * (1 + 1j)) diff --git a/tests/float/float1.py b/tests/float/float1.py index 93f6f014c..137dacc23 100644 --- a/tests/float/float1.py +++ b/tests/float/float1.py @@ -60,6 +60,11 @@ print(1.2 <= -3.4) print(1.2 >= 3.4) print(1.2 >= -3.4) +# comparison of nan is special +nan = float('nan') +print(nan == 1.2) +print(nan == nan) + try: 1.0 / 0 except ZeroDivisionError: diff --git a/tests/float/float_compare.py b/tests/float/float_compare.py new file mode 100644 index 000000000..105923ac7 --- /dev/null +++ b/tests/float/float_compare.py @@ -0,0 +1,22 @@ +# Extended float comparisons + +class Foo: + pass + +foo = Foo() + +print(foo == 1.0) +print(1.0 == foo) +print(1.0 == Foo) +print(1.0 == []) +print(1.0 == {}) + +try: + print(foo < 1.0) +except TypeError: + print("TypeError") + +try: + print(1.0 < foo) +except TypeError: + print("TypeError") diff --git a/tests/io/bytesio_ext2.py b/tests/io/bytesio_ext2.py new file mode 100644 index 000000000..c07ad900c --- /dev/null +++ b/tests/io/bytesio_ext2.py @@ -0,0 +1,13 @@ +try: + import uio as io +except ImportError: + import io + +a = io.BytesIO(b"foobar") +try: + a.seek(-10) +except Exception as e: + # CPython throws ValueError, but MicroPython has consistent stream + # interface, so BytesIO raises the same error as a real file, which + # is OSError(EINVAL). + print(repr(e)) diff --git a/tests/io/bytesio_ext2.py.exp b/tests/io/bytesio_ext2.py.exp new file mode 100644 index 000000000..b52e4978a --- /dev/null +++ b/tests/io/bytesio_ext2.py.exp @@ -0,0 +1 @@ +OSError(22,) diff --git a/tests/micropython/emg_exc.py b/tests/micropython/emg_exc.py index d228e6faa..4a9fa18bc 100644 --- a/tests/micropython/emg_exc.py +++ b/tests/micropython/emg_exc.py @@ -2,6 +2,11 @@ import micropython import sys +try: + import uio +except ImportError: + print("SKIP") + raise SystemExit # some ports need to allocate heap for the emg exc try: @@ -14,7 +19,16 @@ def f(): try: raise ValueError(1) except ValueError as er: - sys.print_exception(er) + exc = er micropython.heap_unlock() + # print the exception + buf = uio.StringIO() + sys.print_exception(exc, buf) + for l in buf.getvalue().split("\n"): + if l.startswith(" File "): + print(l.split('"')[2]) + else: + print(l) + f() diff --git a/tests/micropython/emg_exc.py.exp b/tests/micropython/emg_exc.py.exp index 82b10b5f5..fd2cfb272 100644 --- a/tests/micropython/emg_exc.py.exp +++ b/tests/micropython/emg_exc.py.exp @@ -1 +1,4 @@ -ValueError: +Traceback (most recent call last): +, line 20, in f +ValueError: 1 + diff --git a/tests/misc/non_compliant.py b/tests/misc/non_compliant.py index b4c90e9fc..152633c3b 100644 --- a/tests/misc/non_compliant.py +++ b/tests/misc/non_compliant.py @@ -39,18 +39,6 @@ try: except NotImplementedError: print('NotImplementedError') -# should raise type error -try: - print(set('12') >= '1') -except TypeError: - print('TypeError') - -# should raise type error -try: - print(set('12') <= '123') -except TypeError: - print('TypeError') - # uPy raises TypeError, shold be ValueError try: '%c' % b'\x01\x02' diff --git a/tests/misc/non_compliant.py.exp b/tests/misc/non_compliant.py.exp index ba5590acc..9c157fd5b 100644 --- a/tests/misc/non_compliant.py.exp +++ b/tests/misc/non_compliant.py.exp @@ -3,8 +3,6 @@ AttributeError TypeError NotImplementedError NotImplementedError -True -True TypeError, ValueError NotImplementedError NotImplementedError diff --git a/tests/net_hosted/ssl_getpeercert.py b/tests/net_hosted/ssl_getpeercert.py new file mode 100644 index 000000000..e265c830d --- /dev/null +++ b/tests/net_hosted/ssl_getpeercert.py @@ -0,0 +1,21 @@ +# test ssl.getpeercert() method + +try: + import usocket as socket + import ussl as ssl +except: + import socket + import ssl + + +def test(peer_addr): + s = socket.socket() + s.connect(peer_addr) + s = ssl.wrap_socket(s) + cert = s.getpeercert(True) + print(type(cert), len(cert) > 100) + s.close() + + +if __name__ == "__main__": + test(socket.getaddrinfo('micropython.org', 443)[0][-1]) diff --git a/tests/net_hosted/ssl_getpeercert.py.exp b/tests/net_hosted/ssl_getpeercert.py.exp new file mode 100644 index 000000000..ff7ef5adf --- /dev/null +++ b/tests/net_hosted/ssl_getpeercert.py.exp @@ -0,0 +1 @@ +<class 'bytes'> True diff --git a/tests/run-bench-tests b/tests/run-bench-tests index d48b4b7ec..f4a6776cb 100755 --- a/tests/run-bench-tests +++ b/tests/run-bench-tests @@ -13,10 +13,10 @@ from collections import defaultdict # to the correct executable. if os.name == 'nt': CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3.exe') - MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../windows/micropython.exe') + MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../ports/windows/micropython.exe') else: CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3') - MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../unix/micropython') + MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../ports/unix/micropython') def run_tests(pyb, test_dict): test_count = 0 diff --git a/tests/run-tests b/tests/run-tests index f9c26283d..23fc3d910 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -13,10 +13,10 @@ from glob import glob # to the correct executable. if os.name == 'nt': CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3.exe') - MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../windows/micropython.exe') + MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../ports/windows/micropython.exe') else: CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3') - MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../unix/micropython') + MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../ports/unix/micropython') # mpy-cross is only needed if --via-mpy command-line arg is passed MPYCROSS = os.getenv('MICROPY_MPYCROSS', '../mpy-cross/mpy-cross') @@ -103,7 +103,7 @@ def run_micropython(pyb, args, test_file, is_special=False): os.close(master) os.close(slave) else: - output_mupy = subprocess.check_output(args + [test_file]) + output_mupy = subprocess.check_output(args + [test_file], stderr=subprocess.STDOUT) except subprocess.CalledProcessError: return b'CRASH' @@ -124,7 +124,7 @@ def run_micropython(pyb, args, test_file, is_special=False): # run the actual test try: - output_mupy = subprocess.check_output(cmdlist) + output_mupy = subprocess.check_output(cmdlist, stderr=subprocess.STDOUT) except subprocess.CalledProcessError: output_mupy = b'CRASH' @@ -207,32 +207,38 @@ def run_tests(pyb, tests, args, base_path="."): skip_set_type = False skip_async = False skip_const = False + skip_revops = False # Check if micropython.native is supported, and skip such tests if it's not - native = run_feature_check(pyb, args, base_path, 'native_check.py') - if native == b'CRASH': + output = run_feature_check(pyb, args, base_path, 'native_check.py') + if output == 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': + output = run_feature_check(pyb, args, base_path, 'int_big.py') + if output != 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_feature_check(pyb, args, base_path, 'set_check.py') - if native == b'CRASH': + output = run_feature_check(pyb, args, base_path, 'set_check.py') + if output == 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': + output = run_feature_check(pyb, args, base_path, 'async_check.py') + if output == 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': + output = run_feature_check(pyb, args, base_path, 'const.py') + if output == b'CRASH': skip_const = True + # Check if __rOP__ special methods are supported, and skip such tests if it's not + output = run_feature_check(pyb, args, base_path, 'reverse_ops.py') + if output == b'TypeError\n': + skip_revops = True + # Check if emacs repl is supported, and skip such tests if it's not t = run_feature_check(pyb, args, base_path, 'repl_emacs_check.py') if not 'True' in str(t, 'ascii'): @@ -302,6 +308,7 @@ def run_tests(pyb, tests, args, base_path="."): elif args.target == 'esp8266': skip_tests.add('misc/rge_sm.py') # too large elif args.target == 'minimal': + skip_tests.add('basics/class_inplace_op.py') # all special methods not supported skip_tests.add('misc/rge_sm.py') # too large skip_tests.add('micropython/opt_level.py') # don't assume line numbers are stored @@ -338,6 +345,7 @@ def run_tests(pyb, tests, args, base_path="."): skip_tests.add('misc/rge_sm.py') # requires yield 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/emg_exc.py') # because native doesn't have proper traceback info 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 @@ -360,6 +368,7 @@ def run_tests(pyb, tests, args, base_path="."): skip_it |= skip_set_type and is_set_type skip_it |= skip_async and is_async skip_it |= skip_const and is_const + skip_it |= skip_revops and test_name.startswith("class_reverse_op") if skip_it: print("skip ", test_file) diff --git a/tests/unicode/unicode.py b/tests/unicode/unicode.py index 5f29bc1c9..3a35ce894 100644 --- a/tests/unicode/unicode.py +++ b/tests/unicode/unicode.py @@ -33,3 +33,17 @@ try: int('\u0200') except ValueError: print('ValueError') + +# test invalid UTF-8 string +try: + str(b'ab\xa1', 'utf8') +except UnicodeError: + print('UnicodeError') +try: + str(b'ab\xf8', 'utf8') +except UnicodeError: + print('UnicodeError') +try: + str(bytearray(b'ab\xc0a'), 'utf8') +except UnicodeError: + print('UnicodeError') diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index 390ff1669..4c4f66663 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -18,14 +18,16 @@ sts test tes -larg +RuntimeError: +RuntimeError: # repl ame__ __name__ path argv version version_info implementation platform byteorder maxsize exit stdin stdout -stderr modules exc_info print_exception +stderr modules exc_info getsizeof +print_exception ementation # attrtuple (start=1, stop=2, step=3) @@ -37,7 +39,7 @@ ementation 0 0 # runtime utils -TypeError: can't convert str to int +TypeError: unsupported type for : 'str' TypeError: unsupported types for : 'str', 'str' Warning: test # format float |
