summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/basics/bytes.py3
-rw-r--r--tests/basics/class_inplace_op.py47
-rw-r--r--tests/basics/class_new.py33
-rw-r--r--tests/basics/class_notimpl.py50
-rw-r--r--tests/basics/class_reverse_op.py18
-rw-r--r--tests/basics/containment.py11
-rw-r--r--tests/basics/list_compare.py10
-rw-r--r--tests/basics/object_new.py14
-rw-r--r--tests/basics/set_binop.py12
-rw-r--r--tests/basics/set_remove.py4
-rw-r--r--tests/basics/string_endswith.py5
-rw-r--r--tests/basics/string_endswith_upy.py6
-rw-r--r--tests/basics/string_endswith_upy.py.exp1
-rw-r--r--tests/basics/string_startswith.py5
-rw-r--r--tests/basics/string_startswith_upy.py6
-rw-r--r--tests/basics/string_startswith_upy.py.exp1
-rw-r--r--tests/basics/string_strip.py7
-rw-r--r--tests/basics/struct1.py12
-rw-r--r--tests/basics/struct1_intbig.py2
-rw-r--r--tests/basics/struct2.py37
-rw-r--r--tests/basics/struct_micropython.py3
-rw-r--r--tests/basics/struct_micropython.py.exp1
-rw-r--r--tests/basics/tuple_compare.py10
-rw-r--r--tests/basics/tuple_mult.py5
-rw-r--r--tests/cmdline/cmd_showbc.py.exp28
-rw-r--r--tests/cpydiff/core_locals.py11
-rw-r--r--tests/cpydiff/core_locals_eval.py14
-rw-r--r--tests/extmod/ubinascii_a2b_base64.py7
-rw-r--r--tests/extmod/ure_stack_overflow.py13
-rw-r--r--tests/extmod/ure_stack_overflow.py.exp1
-rw-r--r--tests/feature_check/reverse_ops.py9
-rw-r--r--tests/feature_check/reverse_ops.py.exp0
-rw-r--r--tests/float/complex1.py9
-rw-r--r--tests/float/float1.py5
-rw-r--r--tests/float/float_compare.py22
-rw-r--r--tests/io/bytesio_ext2.py13
-rw-r--r--tests/io/bytesio_ext2.py.exp1
-rw-r--r--tests/micropython/emg_exc.py16
-rw-r--r--tests/micropython/emg_exc.py.exp5
-rw-r--r--tests/misc/non_compliant.py12
-rw-r--r--tests/misc/non_compliant.py.exp2
-rw-r--r--tests/net_hosted/ssl_getpeercert.py21
-rw-r--r--tests/net_hosted/ssl_getpeercert.py.exp1
-rwxr-xr-xtests/run-bench-tests4
-rwxr-xr-xtests/run-tests37
-rw-r--r--tests/unicode/unicode.py14
-rw-r--r--tests/unix/extra_coverage.py.exp8
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