summaryrefslogtreecommitdiff
path: root/tests/basics
diff options
context:
space:
mode:
authorScott Shawcroft <scott@tannewt.org>2018-07-30 12:33:44 -0700
committerGitHub <noreply@github.com>2018-07-30 12:33:44 -0700
commita6d94b68453b8535398ff0b61cd6c4a0c7f77f8b (patch)
tree8defd6392975b8145dc11f0cce9c39a4e440b32a /tests/basics
parent433a29bb70d51abb84c77a911ced43c6ff14706e (diff)
parentb1006170f1dcfa3a9499ef31c19c8f20736b136a (diff)
Merge pull request #1068 from dhalbert/micropython-25ae98f-merge
Micropython 25ae98f merge
Diffstat (limited to 'tests/basics')
-rw-r--r--tests/basics/builtin_abs_intbig.py4
-rw-r--r--tests/basics/builtin_compile.py1
-rw-r--r--tests/basics/builtin_dir.py19
-rw-r--r--tests/basics/builtin_enumerate.py (renamed from tests/basics/enumerate.py)7
-rw-r--r--tests/basics/builtin_eval.py6
-rw-r--r--tests/basics/builtin_eval_error.py6
-rw-r--r--tests/basics/builtin_exec.py8
-rw-r--r--tests/basics/builtin_filter.py (renamed from tests/basics/filter.py)0
-rw-r--r--tests/basics/builtin_getattr.py (renamed from tests/basics/getattr1.py)0
-rw-r--r--tests/basics/builtin_hasattr.py (renamed from tests/basics/hasattr1.py)11
-rw-r--r--tests/basics/builtin_hash_intbig.py3
-rw-r--r--tests/basics/builtin_locals.py9
-rw-r--r--tests/basics/builtin_map.py (renamed from tests/basics/map.py)0
-rw-r--r--tests/basics/builtin_pow3.py6
-rw-r--r--tests/basics/builtin_print.py (renamed from tests/basics/print.py)0
-rw-r--r--tests/basics/builtin_property.py6
-rw-r--r--tests/basics/builtin_property_inherit.py53
-rw-r--r--tests/basics/builtin_range.py3
-rw-r--r--tests/basics/builtin_range_binop.py32
-rw-r--r--tests/basics/builtin_round_int.py18
-rw-r--r--tests/basics/builtin_round_intbig.py17
-rw-r--r--tests/basics/builtin_setattr.py (renamed from tests/basics/setattr1.py)7
-rw-r--r--tests/basics/builtin_type.py18
-rw-r--r--tests/basics/builtin_zip.py (renamed from tests/basics/zip.py)0
-rw-r--r--tests/basics/bytes.py6
-rw-r--r--tests/basics/class_descriptor.py8
-rw-r--r--tests/basics/class_inherit_mul.py5
-rw-r--r--tests/basics/class_super.py17
-rw-r--r--tests/basics/class_super_multinherit.py16
-rw-r--r--tests/basics/del_attr.py7
-rw-r--r--tests/basics/deque1.py68
-rw-r--r--tests/basics/deque2.py66
-rw-r--r--tests/basics/deque2.py.exp15
-rw-r--r--tests/basics/dict_fixed.py48
-rw-r--r--tests/basics/dict_fixed.py.exp7
-rw-r--r--tests/basics/errno1.py4
-rw-r--r--tests/basics/errno1.py.exp1
-rw-r--r--tests/basics/fun_calldblstar.py5
-rw-r--r--tests/basics/fun_calldblstar2.py6
-rw-r--r--tests/basics/fun_error.py45
-rw-r--r--tests/basics/fun_error2.py14
-rw-r--r--tests/basics/fun_name.py1
-rw-r--r--tests/basics/gc1.py5
-rw-r--r--tests/basics/gen_yield_from.py13
-rw-r--r--tests/basics/gen_yield_from_executing.py15
-rw-r--r--tests/basics/gen_yield_from_throw3.py27
-rw-r--r--tests/basics/generator_pend_throw.py31
-rw-r--r--tests/basics/generator_pend_throw.py.exp5
-rw-r--r--tests/basics/int_big1.py13
-rw-r--r--tests/basics/int_big_add.py5
-rw-r--r--tests/basics/int_big_rshift.py6
-rw-r--r--tests/basics/int_big_xor.py3
-rw-r--r--tests/basics/int_constfolding.py6
-rw-r--r--tests/basics/iter1.py9
-rw-r--r--tests/basics/lexer.py7
-rw-r--r--tests/basics/memoryerror.py7
-rw-r--r--tests/basics/memoryerror.py.exp1
-rw-r--r--tests/basics/namedtuple_asdict.py20
-rw-r--r--tests/basics/op_error.py99
-rw-r--r--tests/basics/op_error_intbig.py5
-rw-r--r--tests/basics/op_error_memoryview.py15
-rw-r--r--tests/basics/python34.py6
-rw-r--r--tests/basics/python36.py10
-rw-r--r--tests/basics/python36.py.exp5
-rw-r--r--tests/basics/set_binop.py6
-rw-r--r--tests/basics/set_isfooset.py3
-rw-r--r--tests/basics/special_methods2.py37
-rw-r--r--tests/basics/string_compare.py3
-rw-r--r--tests/basics/subclass_native_call.py30
-rw-r--r--tests/basics/subclass_native_call.py.exp1
-rw-r--r--tests/basics/subclass_native_containment.py22
-rw-r--r--tests/basics/subclass_native_init.py44
-rw-r--r--tests/basics/subclass_native_iter.py7
-rw-r--r--tests/basics/syntaxerror.py10
-rw-r--r--tests/basics/sys_getsizeof.py22
-rw-r--r--tests/basics/try_return.py11
76 files changed, 987 insertions, 95 deletions
diff --git a/tests/basics/builtin_abs_intbig.py b/tests/basics/builtin_abs_intbig.py
index 3dd5ea89f..8afb7fc69 100644
--- a/tests/basics/builtin_abs_intbig.py
+++ b/tests/basics/builtin_abs_intbig.py
@@ -7,3 +7,7 @@ print(abs(-123456789012345678901234567890))
# edge cases for 32 and 64 bit archs (small int overflow when negating)
print(abs(-0x3fffffff - 1))
print(abs(-0x3fffffffffffffff - 1))
+
+# edge case for nan-boxing with 47-bit small int
+i = -0x3fffffffffff
+print(abs(i - 1))
diff --git a/tests/basics/builtin_compile.py b/tests/basics/builtin_compile.py
index 32c6667d8..bf272aca1 100644
--- a/tests/basics/builtin_compile.py
+++ b/tests/basics/builtin_compile.py
@@ -46,3 +46,4 @@ if have_compile():
test()
else:
print("SKIP")
+ raise SystemExit
diff --git a/tests/basics/builtin_dir.py b/tests/basics/builtin_dir.py
index 16e7e669e..c15a76f4c 100644
--- a/tests/basics/builtin_dir.py
+++ b/tests/basics/builtin_dir.py
@@ -17,3 +17,22 @@ foo = Foo()
print('__init__' in dir(foo))
print('x' in dir(foo))
+# dir of subclass
+class A:
+ def a():
+ pass
+class B(A):
+ def b():
+ pass
+d = dir(B())
+print(d.count('a'), d.count('b'))
+
+# dir of class with multiple bases and a common parent
+class C(A):
+ def c():
+ pass
+class D(B, C):
+ def d():
+ pass
+d = dir(D())
+print(d.count('a'), d.count('b'), d.count('c'), d.count('d'))
diff --git a/tests/basics/enumerate.py b/tests/basics/builtin_enumerate.py
index 00595cb0f..29b1dd46c 100644
--- a/tests/basics/enumerate.py
+++ b/tests/basics/builtin_enumerate.py
@@ -8,3 +8,10 @@ print(list(enumerate(range(100))))
print(list(enumerate([1, 2, 3], start=1)))
print(list(enumerate(iterable=[1, 2, 3])))
print(list(enumerate(iterable=[1, 2, 3], start=1)))
+
+# check handling of extra positional args (exercises some logic in mp_arg_parse_all)
+# don't print anything because it doesn't error with MICROPY_CPYTHON_COMPAT disabled
+try:
+ enumerate([], 1, 2)
+except TypeError:
+ pass
diff --git a/tests/basics/builtin_eval.py b/tests/basics/builtin_eval.py
index 8b9d02e61..9b49a2015 100644
--- a/tests/basics/builtin_eval.py
+++ b/tests/basics/builtin_eval.py
@@ -1,5 +1,11 @@
# builtin eval
+try:
+ eval
+except NameError:
+ print("SKIP")
+ raise SystemExit
+
eval('1 + 2')
eval('1 + 2\n')
eval('1 + 2\n\n#comment\n')
diff --git a/tests/basics/builtin_eval_error.py b/tests/basics/builtin_eval_error.py
index 671eedab6..ef0a32da0 100644
--- a/tests/basics/builtin_eval_error.py
+++ b/tests/basics/builtin_eval_error.py
@@ -1,6 +1,12 @@
# test if eval raises SyntaxError
try:
+ eval
+except NameError:
+ print("SKIP")
+ raise SystemExit
+
+try:
print(eval("[1,,]"))
except SyntaxError:
print("SyntaxError")
diff --git a/tests/basics/builtin_exec.py b/tests/basics/builtin_exec.py
index fd4e65c53..2e417a43a 100644
--- a/tests/basics/builtin_exec.py
+++ b/tests/basics/builtin_exec.py
@@ -1,3 +1,11 @@
+# test builtin exec
+
+try:
+ exec
+except NameError:
+ print("SKIP")
+ raise SystemExit
+
print(exec("def foo(): return 42"))
print(foo())
diff --git a/tests/basics/filter.py b/tests/basics/builtin_filter.py
index c6d97cf9b..c6d97cf9b 100644
--- a/tests/basics/filter.py
+++ b/tests/basics/builtin_filter.py
diff --git a/tests/basics/getattr1.py b/tests/basics/builtin_getattr.py
index 59cb7e7f7..59cb7e7f7 100644
--- a/tests/basics/getattr1.py
+++ b/tests/basics/builtin_getattr.py
diff --git a/tests/basics/hasattr1.py b/tests/basics/builtin_hasattr.py
index 118a19e57..c60033b96 100644
--- a/tests/basics/hasattr1.py
+++ b/tests/basics/builtin_hasattr.py
@@ -21,12 +21,19 @@ class C:
def __getattr__(self, attr):
if attr == "exists":
return attr
+ elif attr == "raise":
+ raise Exception(123)
raise AttributeError
c = C()
print(hasattr(c, "exists"))
-# TODO
-#print(hasattr(c, "doesnt_exist"))
+print(hasattr(c, "doesnt_exist"))
+
+# ensure that non-AttributeError exceptions propagate out of hasattr
+try:
+ hasattr(c, "raise")
+except Exception as er:
+ print(er)
try:
hasattr(1, b'123')
diff --git a/tests/basics/builtin_hash_intbig.py b/tests/basics/builtin_hash_intbig.py
index 0092c0f3a..df51f72ab 100644
--- a/tests/basics/builtin_hash_intbig.py
+++ b/tests/basics/builtin_hash_intbig.py
@@ -8,3 +8,6 @@ class F:
def __hash__(self):
return 1 << 70 | 1
print(hash(F()) != 0)
+
+# this had a particular error with internal integer arithmetic of hash function
+print(hash(6699999999999999999999999999999999999999999999999999999999999999999999) != 0)
diff --git a/tests/basics/builtin_locals.py b/tests/basics/builtin_locals.py
index 3689216ef..e60759a40 100644
--- a/tests/basics/builtin_locals.py
+++ b/tests/basics/builtin_locals.py
@@ -2,3 +2,12 @@
x = 123
print(locals()['x'])
+
+class A:
+ y = 1
+ def f(self):
+ pass
+
+ print('x' in locals())
+ print(locals()['y'])
+ print('f' in locals())
diff --git a/tests/basics/map.py b/tests/basics/builtin_map.py
index 8fce352c2..8fce352c2 100644
--- a/tests/basics/map.py
+++ b/tests/basics/builtin_map.py
diff --git a/tests/basics/builtin_pow3.py b/tests/basics/builtin_pow3.py
index 293a5acc9..b9e0b8e04 100644
--- a/tests/basics/builtin_pow3.py
+++ b/tests/basics/builtin_pow3.py
@@ -7,6 +7,12 @@ except NotImplementedError:
print("SKIP")
raise SystemExit
+# test some edge cases
+print(pow(1, 1, 1))
+print(pow(0, 1, 1))
+print(pow(1, 0, 1))
+print(pow(1, 0, 2))
+
# 3 arg pow is defined to only work on integers
try:
print(pow("x", 5, 6))
diff --git a/tests/basics/print.py b/tests/basics/builtin_print.py
index 8b53e32c9..8b53e32c9 100644
--- a/tests/basics/print.py
+++ b/tests/basics/builtin_print.py
diff --git a/tests/basics/builtin_property.py b/tests/basics/builtin_property.py
index 89c3d4936..4b08ee9d3 100644
--- a/tests/basics/builtin_property.py
+++ b/tests/basics/builtin_property.py
@@ -105,3 +105,9 @@ class E:
# not tested for because the other keyword arguments are not accepted
# q = property(fget=lambda self: 21, doc="Half the truth.")
print(E().p)
+
+# a property as an instance member should not be delegated to
+class F:
+ def __init__(self):
+ self.prop_member = property()
+print(type(F().prop_member))
diff --git a/tests/basics/builtin_property_inherit.py b/tests/basics/builtin_property_inherit.py
new file mode 100644
index 000000000..27a091393
--- /dev/null
+++ b/tests/basics/builtin_property_inherit.py
@@ -0,0 +1,53 @@
+# test builtin property combined with inheritance
+try:
+ property
+except:
+ print("SKIP")
+ raise SystemExit
+
+# test property in a base class works for derived classes
+class A:
+ @property
+ def x(self):
+ print('A x')
+ return 123
+class B(A):
+ pass
+class C(B):
+ pass
+class D:
+ pass
+class E(C, D):
+ pass
+print(A().x)
+print(B().x)
+print(C().x)
+print(E().x)
+
+# test that we can add a property to base class after creation
+class F:
+ pass
+F.foo = property(lambda self: print('foo get'))
+class G(F):
+ pass
+F().foo
+G().foo
+
+# should be able to add a property to already-subclassed class because it already has one
+F.bar = property(lambda self: print('bar get'))
+F().bar
+G().bar
+
+# test case where class (H here) is already subclassed before adding attributes
+class H:
+ pass
+class I(H):
+ pass
+
+# should be able to add a normal member to already-subclassed class
+H.val = 2
+print(I().val)
+
+# should be able to add a property to the derived class
+I.baz = property(lambda self: print('baz get'))
+I().baz
diff --git a/tests/basics/builtin_range.py b/tests/basics/builtin_range.py
index 0e2fabd82..66226bad1 100644
--- a/tests/basics/builtin_range.py
+++ b/tests/basics/builtin_range.py
@@ -38,6 +38,9 @@ print(range(1, 100, 5)[15:5:-3])
print(range(100, 1, -5)[5:15:3])
print(range(100, 1, -5)[15:5:-3])
+# for this case uPy gives a different stop value but the listed elements are still correct
+print(list(range(7, -2, -4)[2:-2:]))
+
# zero step
try:
range(1, 2, 0)
diff --git a/tests/basics/builtin_range_binop.py b/tests/basics/builtin_range_binop.py
new file mode 100644
index 000000000..e4e054c27
--- /dev/null
+++ b/tests/basics/builtin_range_binop.py
@@ -0,0 +1,32 @@
+# test binary operations on range objects; (in)equality only
+
+# this "feature test" actually tests the implementation but is the best we can do
+if range(1) != range(1):
+ print("SKIP")
+ raise SystemExit
+
+# basic (in)equality
+print(range(1) == range(1))
+print(range(1) != range(1))
+print(range(1) != range(2))
+
+# empty range
+print(range(0) == range(0))
+print(range(1, 0) == range(0))
+print(range(1, 4, -1) == range(6, 3))
+
+# 1 element range
+print(range(1, 4, 10) == range(1, 4, 10))
+print(range(1, 4, 10) == range(1, 4, 20))
+print(range(1, 4, 10) == range(1, 8, 20))
+
+# more than 1 element
+print(range(0, 3, 2) == range(0, 3, 2))
+print(range(0, 3, 2) == range(0, 4, 2))
+print(range(0, 3, 2) == range(0, 5, 2))
+
+# unsupported binary op
+try:
+ range(1) + 10
+except TypeError:
+ print('TypeError')
diff --git a/tests/basics/builtin_round_int.py b/tests/basics/builtin_round_int.py
new file mode 100644
index 000000000..a2017622a
--- /dev/null
+++ b/tests/basics/builtin_round_int.py
@@ -0,0 +1,18 @@
+# test round() with integer values and second arg
+
+# rounding integers is an optional feature so test for it
+try:
+ round(1, -1)
+except NotImplementedError:
+ print('SKIP')
+ raise SystemExit
+
+tests = [
+ (1, False), (1, True),
+ (124, -1), (125, -1), (126, -1),
+ (5, -1), (15, -1), (25, -1),
+ (12345, 0), (12345, -1), (12345, 1),
+ (-1234, 0), (-1234, -1), (-1234, 1),
+]
+for t in tests:
+ print(round(*t))
diff --git a/tests/basics/builtin_round_intbig.py b/tests/basics/builtin_round_intbig.py
new file mode 100644
index 000000000..adf9d29f2
--- /dev/null
+++ b/tests/basics/builtin_round_intbig.py
@@ -0,0 +1,17 @@
+# test round() with large integer values and second arg
+
+# rounding integers is an optional feature so test for it
+try:
+ round(1, -1)
+except NotImplementedError:
+ print('SKIP')
+ raise SystemExit
+
+i = 2**70
+
+tests = [
+ (i, 0), (i, -1), (i, -10), (i, 1),
+ (-i, 0), (-i, -1), (-i, -10), (-i, 1),
+]
+for t in tests:
+ print(round(*t))
diff --git a/tests/basics/setattr1.py b/tests/basics/builtin_setattr.py
index 9693aca81..e4acb14ca 100644
--- a/tests/basics/setattr1.py
+++ b/tests/basics/builtin_setattr.py
@@ -16,3 +16,10 @@ try:
setattr(a, b'var3', 1)
except TypeError:
print('TypeError')
+
+# try setattr on a built-in function
+try:
+ setattr(int, 'to_bytes', 1)
+except (AttributeError, TypeError):
+ # uPy raises AttributeError, CPython raises TypeError
+ print('AttributeError/TypeError')
diff --git a/tests/basics/builtin_type.py b/tests/basics/builtin_type.py
index 83c45c64b..c5fb36626 100644
--- a/tests/basics/builtin_type.py
+++ b/tests/basics/builtin_type.py
@@ -11,3 +11,21 @@ try:
type(1, 2)
except TypeError:
print('TypeError')
+
+# second arg should be a tuple
+try:
+ type('abc', None, None)
+except TypeError:
+ print('TypeError')
+
+# third arg should be a dict
+try:
+ type('abc', (), None)
+except TypeError:
+ print('TypeError')
+
+# elements of second arg (the bases) should be types
+try:
+ type('abc', (1,), {})
+except TypeError:
+ print('TypeError')
diff --git a/tests/basics/zip.py b/tests/basics/builtin_zip.py
index 66f2544e5..66f2544e5 100644
--- a/tests/basics/zip.py
+++ b/tests/basics/builtin_zip.py
diff --git a/tests/basics/bytes.py b/tests/basics/bytes.py
index 1d97e6b16..0b6b14fa5 100644
--- a/tests/basics/bytes.py
+++ b/tests/basics/bytes.py
@@ -56,3 +56,9 @@ print(x[0], x[1], x[2], x[3])
print(bytes([128, 255]))
# For sequence of unknown len
print(bytes(iter([128, 255])))
+
+# Shouldn't be able to make bytes with negative length
+try:
+ bytes(-1)
+except ValueError:
+ print('ValueError')
diff --git a/tests/basics/class_descriptor.py b/tests/basics/class_descriptor.py
index eb88ba7b9..54f386230 100644
--- a/tests/basics/class_descriptor.py
+++ b/tests/basics/class_descriptor.py
@@ -27,8 +27,8 @@ except AttributeError:
r = m.Forward
if 'Descriptor' in repr(r.__class__):
print('SKIP')
-else:
- print(r)
- m.Forward = 'a'
- del m.Forward
+ raise SystemExit
+print(r)
+m.Forward = 'a'
+del m.Forward
diff --git a/tests/basics/class_inherit_mul.py b/tests/basics/class_inherit_mul.py
index 23476132b..4a43a7f41 100644
--- a/tests/basics/class_inherit_mul.py
+++ b/tests/basics/class_inherit_mul.py
@@ -1,3 +1,5 @@
+# test multiple inheritance of user classes
+
class A:
def __init__(self, x):
print('A init', x)
@@ -30,6 +32,9 @@ class Sub(A, B):
def g(self):
print(self.x)
+print(issubclass(Sub, A))
+print(issubclass(Sub, B))
+
o = Sub()
print(o.x)
o.f()
diff --git a/tests/basics/class_super.py b/tests/basics/class_super.py
index 5a18017ac..629b7ddb4 100644
--- a/tests/basics/class_super.py
+++ b/tests/basics/class_super.py
@@ -41,3 +41,20 @@ except TypeError:
print(True)
else:
print(False)
+
+# first arg to super must be a type
+try:
+ super(1, 1)
+except TypeError:
+ print('TypeError')
+
+# store/delete of super attribute not allowed
+assert hasattr(super(B, B()), 'foo')
+try:
+ super(B, B()).foo = 1
+except AttributeError:
+ print('AttributeError')
+try:
+ del super(B, B()).foo
+except AttributeError:
+ print('AttributeError')
diff --git a/tests/basics/class_super_multinherit.py b/tests/basics/class_super_multinherit.py
new file mode 100644
index 000000000..642a73ce1
--- /dev/null
+++ b/tests/basics/class_super_multinherit.py
@@ -0,0 +1,16 @@
+# test super with multiple inheritance
+
+class A:
+ def foo(self):
+ print('A.foo')
+
+class B:
+ def foo(self):
+ print('B.foo')
+
+class C(A, B):
+ def foo(self):
+ print('C.foo')
+ super().foo()
+
+C().foo()
diff --git a/tests/basics/del_attr.py b/tests/basics/del_attr.py
index bec7afb84..8487b97e3 100644
--- a/tests/basics/del_attr.py
+++ b/tests/basics/del_attr.py
@@ -30,3 +30,10 @@ try:
del c.x
except AttributeError:
print("AttributeError")
+
+# try to del an attribute of a built-in class
+try:
+ del int.to_bytes
+except (AttributeError, TypeError):
+ # uPy raises AttributeError, CPython raises TypeError
+ print('AttributeError/TypeError')
diff --git a/tests/basics/deque1.py b/tests/basics/deque1.py
new file mode 100644
index 000000000..19966fcb0
--- /dev/null
+++ b/tests/basics/deque1.py
@@ -0,0 +1,68 @@
+try:
+ try:
+ from ucollections import deque
+ except ImportError:
+ from collections import deque
+except ImportError:
+ print("SKIP")
+ raise SystemExit
+
+
+d = deque((), 2)
+print(len(d))
+print(bool(d))
+
+try:
+ d.popleft()
+except IndexError:
+ print("IndexError")
+
+print(d.append(1))
+print(len(d))
+print(bool(d))
+print(d.popleft())
+print(len(d))
+
+d.append(2)
+print(d.popleft())
+
+d.append(3)
+d.append(4)
+print(len(d))
+print(d.popleft(), d.popleft())
+try:
+ d.popleft()
+except IndexError:
+ print("IndexError")
+
+d.append(5)
+d.append(6)
+d.append(7)
+print(len(d))
+print(d.popleft(), d.popleft())
+print(len(d))
+try:
+ d.popleft()
+except IndexError:
+ print("IndexError")
+
+# Case where get index wraps around when appending to full deque
+d = deque((), 2)
+d.append(1)
+d.append(2)
+d.append(3)
+d.append(4)
+d.append(5)
+print(d.popleft(), d.popleft())
+
+# Negative maxlen is not allowed
+try:
+ deque((), -1)
+except ValueError:
+ print("ValueError")
+
+# Unsupported unary op
+try:
+ ~d
+except TypeError:
+ print("TypeError")
diff --git a/tests/basics/deque2.py b/tests/basics/deque2.py
new file mode 100644
index 000000000..22d370e94
--- /dev/null
+++ b/tests/basics/deque2.py
@@ -0,0 +1,66 @@
+# Tests for deques with "check overflow" flag and other extensions
+# wrt to CPython.
+try:
+ try:
+ from ucollections import deque
+ except ImportError:
+ from collections import deque
+except ImportError:
+ print("SKIP")
+ raise SystemExit
+
+
+# Initial sequence is not supported
+try:
+ deque([1, 2, 3], 10)
+except ValueError:
+ print("ValueError")
+
+# Not even empty list, only empty tuple
+try:
+ deque([], 10)
+except ValueError:
+ print("ValueError")
+
+# Only fixed-size deques are supported, so length arg is mandatory
+try:
+ deque(())
+except TypeError:
+ print("TypeError")
+
+d = deque((), 2, True)
+
+try:
+ d.popleft()
+except IndexError:
+ print("IndexError")
+
+print(d.append(1))
+print(d.popleft())
+
+d.append(2)
+print(d.popleft())
+
+d.append(3)
+d.append(4)
+print(d.popleft(), d.popleft())
+try:
+ d.popleft()
+except IndexError as e:
+ print(repr(e))
+
+d.append(5)
+d.append(6)
+print(len(d))
+try:
+ d.append(7)
+except IndexError as e:
+ print(repr(e))
+print(len(d))
+
+print(d.popleft(), d.popleft())
+print(len(d))
+try:
+ d.popleft()
+except IndexError as e:
+ print(repr(e))
diff --git a/tests/basics/deque2.py.exp b/tests/basics/deque2.py.exp
new file mode 100644
index 000000000..3df8acf40
--- /dev/null
+++ b/tests/basics/deque2.py.exp
@@ -0,0 +1,15 @@
+ValueError
+ValueError
+TypeError
+IndexError
+None
+1
+2
+3 4
+IndexError('empty',)
+2
+IndexError('full',)
+2
+5 6
+0
+IndexError('empty',)
diff --git a/tests/basics/dict_fixed.py b/tests/basics/dict_fixed.py
new file mode 100644
index 000000000..4261a0655
--- /dev/null
+++ b/tests/basics/dict_fixed.py
@@ -0,0 +1,48 @@
+# test that fixed dictionaries cannot be modified
+
+try:
+ import uerrno
+except ImportError:
+ print("SKIP")
+ raise SystemExit
+
+# Save a copy of uerrno.errorcode, so we can check later
+# that it hasn't been modified.
+errorcode_copy = uerrno.errorcode.copy()
+
+try:
+ uerrno.errorcode.popitem()
+except TypeError:
+ print("TypeError")
+
+try:
+ uerrno.errorcode.pop(0)
+except TypeError:
+ print("TypeError")
+
+try:
+ uerrno.errorcode.setdefault(0, 0)
+except TypeError:
+ print("TypeError")
+
+try:
+ uerrno.errorcode.update([(1, 2)])
+except TypeError:
+ print("TypeError")
+
+try:
+ del uerrno.errorcode[1]
+except TypeError:
+ print("TypeError")
+
+try:
+ uerrno.errorcode[1] = 'foo'
+except TypeError:
+ print("TypeError")
+
+try:
+ uerrno.errorcode.clear()
+except TypeError:
+ print("TypeError")
+
+assert uerrno.errorcode == errorcode_copy
diff --git a/tests/basics/dict_fixed.py.exp b/tests/basics/dict_fixed.py.exp
new file mode 100644
index 000000000..ffaeb4085
--- /dev/null
+++ b/tests/basics/dict_fixed.py.exp
@@ -0,0 +1,7 @@
+TypeError
+TypeError
+TypeError
+TypeError
+TypeError
+TypeError
+TypeError
diff --git a/tests/basics/errno1.py b/tests/basics/errno1.py
index bbbfac10c..cef5326b4 100644
--- a/tests/basics/errno1.py
+++ b/tests/basics/errno1.py
@@ -18,3 +18,7 @@ print(msg[:7], msg[msg.find(']'):])
# check that unknown errno is still rendered
print(str(OSError(9999)))
+
+# this tests a failed constant lookup in errno
+errno = uerrno
+print(errno.__name__)
diff --git a/tests/basics/errno1.py.exp b/tests/basics/errno1.py.exp
index b5dd529e4..b55046898 100644
--- a/tests/basics/errno1.py.exp
+++ b/tests/basics/errno1.py.exp
@@ -2,3 +2,4 @@
[Errno ] Input/output error
[Errno ] ENOBUFS
9999
+uerrno
diff --git a/tests/basics/fun_calldblstar.py b/tests/basics/fun_calldblstar.py
index 15038b2f5..d4816c5cd 100644
--- a/tests/basics/fun_calldblstar.py
+++ b/tests/basics/fun_calldblstar.py
@@ -6,6 +6,11 @@ def f(a, b):
f(1, **{'b':2})
f(1, **{'b':val for val in range(1)})
+try:
+ f(1, **{len:2})
+except TypeError:
+ print('TypeError')
+
# test calling a method with keywords given by **dict
class A:
diff --git a/tests/basics/fun_calldblstar2.py b/tests/basics/fun_calldblstar2.py
index cf982ef5b..8795eaf15 100644
--- a/tests/basics/fun_calldblstar2.py
+++ b/tests/basics/fun_calldblstar2.py
@@ -1,5 +1,11 @@
# test passing a string object as the key for a keyword argument
+try:
+ exec
+except NameError:
+ print("SKIP")
+ raise SystemExit
+
# they key in this dict is a string object and is not interned
args = {'thisisaverylongargumentname': 123}
diff --git a/tests/basics/fun_error.py b/tests/basics/fun_error.py
index 367fe0b7f..3e79c727b 100644
--- a/tests/basics/fun_error.py
+++ b/tests/basics/fun_error.py
@@ -1,31 +1,44 @@
# test errors from bad function calls
-def test_exc(code, exc):
- try:
- exec(code)
- print("no exception")
- except exc:
- print("right exception")
- except:
- print("wrong exception")
-
# function doesn't take keyword args
-test_exc("[].append(x=1)", TypeError)
+try:
+ [].append(x=1)
+except TypeError:
+ print('TypeError')
# function with variable number of positional args given too few
-test_exc("round()", TypeError)
+try:
+ round()
+except TypeError:
+ print('TypeError')
# function with variable number of positional args given too many
-test_exc("round(1, 2, 3)", TypeError)
+try:
+ round(1, 2, 3)
+except TypeError:
+ print('TypeError')
# function with fixed number of positional args given wrong number
-test_exc("[].append(1, 2)", TypeError)
+try:
+ [].append(1, 2)
+except TypeError:
+ print('TypeError')
# function with keyword args given extra positional args
-test_exc("[].sort(1)", TypeError)
+try:
+ [].sort(1)
+except TypeError:
+ print('TypeError')
# function with keyword args given extra keyword args
-test_exc("[].sort(noexist=1)", TypeError)
+try:
+ [].sort(noexist=1)
+except TypeError:
+ print('TypeError')
# kw given for positional, but a different positional is missing
-test_exc("def f(x, y): pass\nf(x=1)", TypeError)
+try:
+ def f(x, y): pass
+ f(x=1)
+except TypeError:
+ print('TypeError')
diff --git a/tests/basics/fun_error2.py b/tests/basics/fun_error2.py
index 2a00396e6..39fd0af14 100644
--- a/tests/basics/fun_error2.py
+++ b/tests/basics/fun_error2.py
@@ -5,14 +5,8 @@ except:
print("SKIP")
raise SystemExit
-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)
+try:
+ enumerate()
+except TypeError:
+ print('TypeError')
diff --git a/tests/basics/fun_name.py b/tests/basics/fun_name.py
index 7a84fc339..a724f4111 100644
--- a/tests/basics/fun_name.py
+++ b/tests/basics/fun_name.py
@@ -14,3 +14,4 @@ try:
print(A().Fun.__name__)
except AttributeError:
print('SKIP')
+ raise SystemExit
diff --git a/tests/basics/gc1.py b/tests/basics/gc1.py
index dcbe0bfcf..332bf9744 100644
--- a/tests/basics/gc1.py
+++ b/tests/basics/gc1.py
@@ -27,3 +27,8 @@ if hasattr(gc, 'threshold'):
assert(gc.threshold() == 0)
assert(gc.threshold(-1) is None)
assert(gc.threshold() == -1)
+
+ # Setting a low threshold should trigger collection at the list alloc
+ gc.threshold(1)
+ [[], []]
+ gc.threshold(-1)
diff --git a/tests/basics/gen_yield_from.py b/tests/basics/gen_yield_from.py
index 5196b48d2..4e68aec63 100644
--- a/tests/basics/gen_yield_from.py
+++ b/tests/basics/gen_yield_from.py
@@ -40,3 +40,16 @@ def gen6():
g = gen6()
print(list(g))
+
+# StopIteration from within a Python function, within a native iterator (map), within a yield from
+def gen7(x):
+ if x < 3:
+ return x
+ else:
+ raise StopIteration(444)
+
+def gen8():
+ print((yield from map(gen7, range(100))))
+
+g = gen8()
+print(list(g))
diff --git a/tests/basics/gen_yield_from_executing.py b/tests/basics/gen_yield_from_executing.py
new file mode 100644
index 000000000..cad0c7695
--- /dev/null
+++ b/tests/basics/gen_yield_from_executing.py
@@ -0,0 +1,15 @@
+# yielding from an already executing generator is not allowed
+
+def f():
+ yield 1
+ # g here is already executing so this will raise an exception
+ yield from g
+
+g = f()
+
+print(next(g))
+
+try:
+ next(g)
+except ValueError:
+ print('ValueError')
diff --git a/tests/basics/gen_yield_from_throw3.py b/tests/basics/gen_yield_from_throw3.py
index 0f6c7c842..85b6f71f9 100644
--- a/tests/basics/gen_yield_from_throw3.py
+++ b/tests/basics/gen_yield_from_throw3.py
@@ -28,3 +28,30 @@ print(g.throw(123))
g = gen()
print(next(g))
print(g.throw(ZeroDivisionError))
+
+# this user-defined generator doesn't have a throw() method
+class Iter2:
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ return 1
+
+def gen2():
+ yield from Iter2()
+
+# the thrown ValueError is not intercepted by the user class
+g = gen2()
+print(next(g))
+try:
+ g.throw(ValueError)
+except:
+ print('ValueError')
+
+# the thrown 123 is not an exception so raises a TypeError
+g = gen2()
+print(next(g))
+try:
+ g.throw(123)
+except TypeError:
+ print('TypeError')
diff --git a/tests/basics/generator_pend_throw.py b/tests/basics/generator_pend_throw.py
new file mode 100644
index 000000000..f00ff793b
--- /dev/null
+++ b/tests/basics/generator_pend_throw.py
@@ -0,0 +1,31 @@
+def gen():
+ i = 0
+ while 1:
+ yield i
+ i += 1
+
+g = gen()
+
+try:
+ g.pend_throw
+except AttributeError:
+ print("SKIP")
+ raise SystemExit
+
+
+print(next(g))
+print(next(g))
+g.pend_throw(ValueError())
+
+v = None
+try:
+ v = next(g)
+except Exception as e:
+ print("raised", repr(e))
+
+print("ret was:", v)
+
+try:
+ gen().pend_throw(ValueError())
+except TypeError:
+ print("TypeError")
diff --git a/tests/basics/generator_pend_throw.py.exp b/tests/basics/generator_pend_throw.py.exp
new file mode 100644
index 000000000..ed4d88295
--- /dev/null
+++ b/tests/basics/generator_pend_throw.py.exp
@@ -0,0 +1,5 @@
+0
+1
+raised ValueError()
+ret was: None
+TypeError
diff --git a/tests/basics/int_big1.py b/tests/basics/int_big1.py
index 425bc21b6..40d16c455 100644
--- a/tests/basics/int_big1.py
+++ b/tests/basics/int_big1.py
@@ -75,6 +75,10 @@ try:
print(int("123456789012345678901234567890abcdef"))
except ValueError:
print('ValueError');
+try:
+ print(int("123456789012345678901234567890\x01"))
+except ValueError:
+ print('ValueError');
# test constant integer with more than 255 chars
x = 0x84ce72aa8699df436059f052ac51b6398d2511e49631bcb7e71f89c499b9ee425dfbc13a5f6d408471b054f2655617cbbaf7937b7c80cd8865cf02c8487d30d2b0fbd8b2c4e102e16d828374bbc47b93852f212d5043c3ea720f086178ff798cc4f63f787b9c2e419efa033e7644ea7936f54462dc21a6c4580725f7f0e7d1aaaaaaa
@@ -86,6 +90,11 @@ x = 1073741823 # small
x = -1073741823 # small
x = 1073741824 # big
x = -1073741824 # big
+# for nan-boxing with 47-bit small ints
+print(int('0x3fffffffffff', 16)) # small
+print(int('-0x3fffffffffff', 16)) # small
+print(int('0x400000000000', 16)) # big
+print(int('-0x400000000000', 16)) # big
# for 64 bit archs
x = 4611686018427387903 # small
x = -4611686018427387903 # small
@@ -95,3 +104,7 @@ x = -4611686018427387904 # big
# sys.maxsize is a constant mpz, so test it's compatible with dynamic ones
import sys
print(sys.maxsize + 1 - 1 == sys.maxsize)
+
+# test extraction of big int value via mp_obj_get_int_maybe
+x = 1 << 70
+print('a' * (x + 4 - x))
diff --git a/tests/basics/int_big_add.py b/tests/basics/int_big_add.py
index f0c3336d0..b64b76ff0 100644
--- a/tests/basics/int_big_add.py
+++ b/tests/basics/int_big_add.py
@@ -5,6 +5,11 @@ i = 0x3fffffff
print(i + i)
print(-i + -i)
+# 47-bit overflow
+i = 0x3fffffffffff
+print(i + i)
+print(-i + -i)
+
# 63-bit overflow
i = 0x3fffffffffffffff
print(i + i)
diff --git a/tests/basics/int_big_rshift.py b/tests/basics/int_big_rshift.py
index b2fecb36c..e6e2a6699 100644
--- a/tests/basics/int_big_rshift.py
+++ b/tests/basics/int_big_rshift.py
@@ -3,5 +3,7 @@ print(i >> 1)
print(i >> 1000)
# result needs rounding up
-print(-(1<<70) >> 80)
-print(-0xffffffffffffffff >> 32)
+i = -(1 << 70)
+print(i >> 80)
+i = -0xffffffffffffffff
+print(i >> 32)
diff --git a/tests/basics/int_big_xor.py b/tests/basics/int_big_xor.py
index 318db45e6..cd1d9ae97 100644
--- a/tests/basics/int_big_xor.py
+++ b/tests/basics/int_big_xor.py
@@ -19,7 +19,8 @@ print((-a) ^ (1 << 100))
print((-a) ^ (1 << 200))
print((-a) ^ a == 0)
print(bool((-a) ^ a))
-print(-1 ^ 0xffffffffffffffff) # carry overflows to higher digit
+i = -1
+print(i ^ 0xffffffffffffffff) # carry overflows to higher digit
# test + -
diff --git a/tests/basics/int_constfolding.py b/tests/basics/int_constfolding.py
index 7bb538378..158897f55 100644
--- a/tests/basics/int_constfolding.py
+++ b/tests/basics/int_constfolding.py
@@ -29,3 +29,9 @@ print(123 // 7, 123 % 7)
print(-123 // 7, -123 % 7)
print(123 // -7, 123 % -7)
print(-123 // -7, -123 % -7)
+
+# won't fold so an exception can be raised at runtime
+try:
+ 1 << -1
+except ValueError:
+ print('ValueError')
diff --git a/tests/basics/iter1.py b/tests/basics/iter1.py
index 9117dfd2b..26e9a2ef2 100644
--- a/tests/basics/iter1.py
+++ b/tests/basics/iter1.py
@@ -68,3 +68,12 @@ except StopIteration:
for i in myiter(32):
print(i)
+
+# repeat some of the above tests but use tuple() to walk the iterator (tests mp_iternext)
+print(tuple(myiter(5)))
+print(tuple(myiter(12)))
+print(tuple(myiter(32)))
+try:
+ tuple(myiter(22))
+except TypeError:
+ print('raised TypeError')
diff --git a/tests/basics/lexer.py b/tests/basics/lexer.py
index 244de8cb9..181d62db1 100644
--- a/tests/basics/lexer.py
+++ b/tests/basics/lexer.py
@@ -1,5 +1,12 @@
# test the lexer
+try:
+ eval
+ exec
+except NameError:
+ print("SKIP")
+ raise SystemExit
+
# __debug__ is a special symbol
print(type(__debug__))
diff --git a/tests/basics/memoryerror.py b/tests/basics/memoryerror.py
index ba145b7d4..18053f097 100644
--- a/tests/basics/memoryerror.py
+++ b/tests/basics/memoryerror.py
@@ -1,6 +1,13 @@
+# test out-of-memory with malloc
l = list(range(1000))
try:
1000000000 * l
except MemoryError:
print('MemoryError')
print(len(l), l[0], l[-1])
+
+# test out-of-memory with realloc
+try:
+ [].extend(range(1000000000))
+except MemoryError:
+ print('MemoryError')
diff --git a/tests/basics/memoryerror.py.exp b/tests/basics/memoryerror.py.exp
index c41e8c1a6..3d6c7f000 100644
--- a/tests/basics/memoryerror.py.exp
+++ b/tests/basics/memoryerror.py.exp
@@ -1,2 +1,3 @@
MemoryError
1000 0 999
+MemoryError
diff --git a/tests/basics/namedtuple_asdict.py b/tests/basics/namedtuple_asdict.py
new file mode 100644
index 000000000..c5681376f
--- /dev/null
+++ b/tests/basics/namedtuple_asdict.py
@@ -0,0 +1,20 @@
+try:
+ try:
+ from collections import namedtuple
+ except ImportError:
+ from ucollections import namedtuple
+except ImportError:
+ print("SKIP")
+ raise SystemExit
+
+t = namedtuple("Tup", ["baz", "foo", "bar"])(3, 2, 5)
+
+try:
+ t._asdict
+except AttributeError:
+ print("SKIP")
+ raise SystemExit
+
+d = t._asdict()
+print(list(d.keys()))
+print(list(d.values()))
diff --git a/tests/basics/op_error.py b/tests/basics/op_error.py
index b30b5f0a3..7b4f896e1 100644
--- a/tests/basics/op_error.py
+++ b/tests/basics/op_error.py
@@ -1,44 +1,89 @@
# 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")
-
# unsupported unary operators
-test_exc("~None", TypeError)
-test_exc("~''", TypeError)
-test_exc("~[]", TypeError)
-test_exc("~bytearray()", TypeError)
+try:
+ ~None
+except TypeError:
+ print('TypeError')
+try:
+ ~''
+except TypeError:
+ print('TypeError')
+try:
+ ~[]
+except TypeError:
+ print('TypeError')
+try:
+ ~bytearray()
+except TypeError:
+ print('TypeError')
# unsupported binary operators
-test_exc("False in True", TypeError)
-test_exc("1 * {}", TypeError)
-test_exc("1 in 1", TypeError)
-test_exc("bytearray() // 2", TypeError)
+try:
+ False in True
+except TypeError:
+ print('TypeError')
+try:
+ 1 * {}
+except TypeError:
+ print('TypeError')
+try:
+ 1 in 1
+except TypeError:
+ print('TypeError')
+try:
+ bytearray() // 2
+except TypeError:
+ print('TypeError')
# object with buffer protocol needed on rhs
-test_exc("bytearray(1) + 1", TypeError)
+try:
+ bytearray(1) + 1
+except TypeError:
+ print('TypeError')
# unsupported subscription
-test_exc("1[0]", TypeError)
-test_exc("1[0] = 1", TypeError)
-test_exc("''['']", TypeError)
-test_exc("'a'[0] = 1", TypeError)
-test_exc("del 1[0]", TypeError)
+try:
+ 1[0]
+except TypeError:
+ print('TypeError')
+try:
+ 1[0] = 1
+except TypeError:
+ print('TypeError')
+try:
+ ''['']
+except TypeError:
+ print('TypeError')
+try:
+ 'a'[0] = 1
+except TypeError:
+ print('TypeError')
+try:
+ del 1[0]
+except TypeError:
+ print('TypeError')
# not callable
-test_exc("1()", TypeError)
+try:
+ 1()
+except TypeError:
+ print('TypeError')
# not an iterator
-test_exc("next(1)", TypeError)
+try:
+ next(1)
+except TypeError:
+ print('TypeError')
# must be an exception type
-test_exc("raise 1", TypeError)
+try:
+ raise 1
+except TypeError:
+ print('TypeError')
# no such name in import
-test_exc("from sys import youcannotimportmebecauseidontexist", ImportError)
+try:
+ from sys import youcannotimportmebecauseidontexist
+except ImportError:
+ print('ImportError')
diff --git a/tests/basics/op_error_intbig.py b/tests/basics/op_error_intbig.py
index 432c05a9f..7def75b0c 100644
--- a/tests/basics/op_error_intbig.py
+++ b/tests/basics/op_error_intbig.py
@@ -10,4 +10,7 @@ def test_exc(code, exc):
print("wrong exception")
# object with buffer protocol needed on rhs
-test_exc("(1 << 70) in 1", TypeError)
+try:
+ (1 << 70) in 1
+except TypeError:
+ print('TypeError')
diff --git a/tests/basics/op_error_memoryview.py b/tests/basics/op_error_memoryview.py
index 8d4403f77..233f7f9ab 100644
--- a/tests/basics/op_error_memoryview.py
+++ b/tests/basics/op_error_memoryview.py
@@ -5,14 +5,9 @@ except:
print("SKIP")
raise SystemExit
-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)
+try:
+ m = memoryview(bytearray())
+ m += bytearray()
+except TypeError:
+ print('TypeError')
diff --git a/tests/basics/python34.py b/tests/basics/python34.py
index d5cc59ad6..36531f11c 100644
--- a/tests/basics/python34.py
+++ b/tests/basics/python34.py
@@ -1,5 +1,11 @@
# tests that differ when running under Python 3.4 vs 3.5/3.6
+try:
+ exec
+except NameError:
+ print("SKIP")
+ raise SystemExit
+
# from basics/fun_kwvarargs.py
# test evaluation order of arguments (in 3.4 it's backwards, 3.5 it's fixed)
def f4(*vargs, **kwargs):
diff --git a/tests/basics/python36.py b/tests/basics/python36.py
new file mode 100644
index 000000000..20ecd9227
--- /dev/null
+++ b/tests/basics/python36.py
@@ -0,0 +1,10 @@
+# tests for things that only Python 3.6 supports
+
+# underscores in numeric literals
+print(100_000)
+print(0b1010_0101)
+print(0xff_ff)
+
+# underscore supported by int constructor
+print(int('1_2_3'))
+print(int('0o1_2_3', 8))
diff --git a/tests/basics/python36.py.exp b/tests/basics/python36.py.exp
new file mode 100644
index 000000000..4b65daafa
--- /dev/null
+++ b/tests/basics/python36.py.exp
@@ -0,0 +1,5 @@
+100000
+165
+65535
+123
+83
diff --git a/tests/basics/set_binop.py b/tests/basics/set_binop.py
index bc76533b1..bf55f87db 100644
--- a/tests/basics/set_binop.py
+++ b/tests/basics/set_binop.py
@@ -61,6 +61,12 @@ except TypeError:
# unsupported operator
try:
+ set('abc') * set('abc')
+except TypeError:
+ print('TypeError')
+
+# unsupported operator with RHS not a set
+try:
set('abc') * 2
except TypeError:
print('TypeError')
diff --git a/tests/basics/set_isfooset.py b/tests/basics/set_isfooset.py
index ce7952cd2..27dedea00 100644
--- a/tests/basics/set_isfooset.py
+++ b/tests/basics/set_isfooset.py
@@ -1,5 +1,6 @@
sets = [set(), {1}, {1, 2, 3}, {3, 4, 5}, {5, 6, 7}]
+args = sets + [[1], [1, 2], [1, 2 ,3]]
for i in sets:
- for j in sets:
+ for j in args:
print(i.issubset(j))
print(i.issuperset(j))
diff --git a/tests/basics/special_methods2.py b/tests/basics/special_methods2.py
index ba7cf27cd..c21618e93 100644
--- a/tests/basics/special_methods2.py
+++ b/tests/basics/special_methods2.py
@@ -94,6 +94,9 @@ class Cud():
print("__isub__ called")
return self
+ def __dir__(self):
+ return ['a', 'b', 'c']
+
cud1 = Cud()
cud2 = Cud()
@@ -112,33 +115,25 @@ cud1 / cud2
cud2 // cud1
cud1 += cud2
cud1 -= cud2
+cud1 % 2
+cud1 ** 2
+cud1 | cud2
+cud1 & cud2
+cud1 ^ cud2
+cud1 << 1
+cud1 >> 1
+
+# test that dir() delegates to __dir__ special method
+print(dir(cud1))
+
+# test that dir() does not delegate to __dir__ for the type
+print('a' in dir(Cud))
# 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_compare.py b/tests/basics/string_compare.py
index f011ed363..6515809b3 100644
--- a/tests/basics/string_compare.py
+++ b/tests/basics/string_compare.py
@@ -53,3 +53,6 @@ print("1/" <= "1")
# that does have a hash, but the lengths of the two strings are different
import sys
print(sys.version == 'a long string that has a hash')
+
+# this special string would have a hash of 0 but is incremented to 1
+print('Q+?' == 'Q' + '+?')
diff --git a/tests/basics/subclass_native_call.py b/tests/basics/subclass_native_call.py
new file mode 100644
index 000000000..c64557522
--- /dev/null
+++ b/tests/basics/subclass_native_call.py
@@ -0,0 +1,30 @@
+# test calling a subclass of a native class that supports calling
+
+# For this test we need a native class that can be subclassed (has make_new)
+# and is callable (has call). The only one available is machine.Signal, which
+# in turns needs PinBase.
+try:
+ import umachine as machine
+except ImportError:
+ import machine
+try:
+ machine.PinBase
+ machine.Signal
+except AttributeError:
+ print("SKIP")
+ raise SystemExit
+
+class Pin(machine.PinBase):
+ #def __init__(self):
+ # self.v = 0
+
+ def value(self, v=None):
+ return 42
+
+class MySignal(machine.Signal):
+ pass
+
+s = MySignal(Pin())
+
+# apply call to the subclass, which should call the native base
+print(s())
diff --git a/tests/basics/subclass_native_call.py.exp b/tests/basics/subclass_native_call.py.exp
new file mode 100644
index 000000000..d81cc0710
--- /dev/null
+++ b/tests/basics/subclass_native_call.py.exp
@@ -0,0 +1 @@
+42
diff --git a/tests/basics/subclass_native_containment.py b/tests/basics/subclass_native_containment.py
new file mode 100644
index 000000000..7400f7583
--- /dev/null
+++ b/tests/basics/subclass_native_containment.py
@@ -0,0 +1,22 @@
+# test containment operator on subclass of a native type
+
+class mylist(list):
+ pass
+
+class mydict(dict):
+ pass
+
+class mybytes(bytes):
+ pass
+
+l = mylist([1, 2, 3])
+print(0 in l)
+print(1 in l)
+
+d = mydict({1:1, 2:2})
+print(0 in l)
+print(1 in l)
+
+b = mybytes(b'1234')
+print(0 in b)
+print(b'1' in b)
diff --git a/tests/basics/subclass_native_init.py b/tests/basics/subclass_native_init.py
new file mode 100644
index 000000000..38d2f23ac
--- /dev/null
+++ b/tests/basics/subclass_native_init.py
@@ -0,0 +1,44 @@
+# test subclassing a native type and overriding __init__
+
+# overriding list.__init__()
+class L(list):
+ def __init__(self, a, b):
+ super().__init__([a, b])
+print(L(2, 3))
+
+# inherits implicitly from object
+class A:
+ def __init__(self):
+ print("A.__init__")
+ super().__init__()
+A()
+
+# inherits explicitly from object
+class B(object):
+ def __init__(self):
+ print("B.__init__")
+ super().__init__()
+B()
+
+# multiple inheritance with object explicitly mentioned
+class C:
+ pass
+class D(C, object):
+ def __init__(self):
+ print('D.__init__')
+ super().__init__()
+ def reinit(self):
+ print('D.foo')
+ super().__init__()
+a = D()
+a.__init__()
+a.reinit()
+
+# call __init__() after object is already init'd
+class L(list):
+ def reinit(self):
+ super().__init__(range(2))
+a = L(range(5))
+print(a)
+a.reinit()
+print(a)
diff --git a/tests/basics/subclass_native_iter.py b/tests/basics/subclass_native_iter.py
new file mode 100644
index 000000000..0f6b369ad
--- /dev/null
+++ b/tests/basics/subclass_native_iter.py
@@ -0,0 +1,7 @@
+# test subclassing a native type which can be iterated over
+
+class mymap(map):
+ pass
+
+m = mymap(lambda x: x + 10, range(4))
+print(list(m))
diff --git a/tests/basics/syntaxerror.py b/tests/basics/syntaxerror.py
index 4161de017..8e706c6e2 100644
--- a/tests/basics/syntaxerror.py
+++ b/tests/basics/syntaxerror.py
@@ -1,5 +1,11 @@
# test syntax errors
+try:
+ exec
+except NameError:
+ print("SKIP")
+ raise SystemExit
+
def test_syntax(code):
try:
exec(code)
@@ -29,6 +35,10 @@ test_syntax(" a\n")
# malformed integer literal (parser error)
test_syntax("123z")
+# input doesn't match the grammar (parser error)
+test_syntax('1 or 2 or')
+test_syntax('{1:')
+
# can't assign to literals
test_syntax("1 = 2")
test_syntax("'' = 1")
diff --git a/tests/basics/sys_getsizeof.py b/tests/basics/sys_getsizeof.py
new file mode 100644
index 000000000..fe1b403e0
--- /dev/null
+++ b/tests/basics/sys_getsizeof.py
@@ -0,0 +1,22 @@
+# test sys.getsizeof() function
+
+import sys
+try:
+ sys.getsizeof
+except AttributeError:
+ print('SKIP')
+ raise SystemExit
+
+print(sys.getsizeof([1, 2]) >= 2)
+print(sys.getsizeof({1: 2}) >= 2)
+
+class A:
+ pass
+print(sys.getsizeof(A()) > 0)
+
+# Only test deque if we have it
+try:
+ from ucollections import deque
+ assert sys.getsizeof(deque((), 1)) > 0
+except ImportError:
+ pass
diff --git a/tests/basics/try_return.py b/tests/basics/try_return.py
new file mode 100644
index 000000000..492c18d95
--- /dev/null
+++ b/tests/basics/try_return.py
@@ -0,0 +1,11 @@
+# test use of return with try-except
+
+def f(l, i):
+ try:
+ return l[i]
+ except IndexError:
+ print('IndexError')
+ return -1
+
+print(f([1], 0))
+print(f([], 0))