micropython: add micropython component

This commit is contained in:
KY-zhang-X
2022-09-29 12:10:37 +08:00
parent 1514f1cb9b
commit dd76146324
2679 changed files with 354110 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
# all tests need print to work! make sure it does work
print(1)
print('abc')

View File

@@ -0,0 +1,5 @@
# test short circuit expressions outside if conditionals
print(() or 1)
print((1,) or 1)
print(() and 1)
print((1,) and 1)

View File

@@ -0,0 +1,25 @@
# test PEP 526, varible annotations
x: int
print("x" in globals())
x: int = 1
print(x)
t: tuple = 1, 2
print(t)
# a pure annotation in a function makes that variable local
def f():
x: int
try:
print(x)
except NameError:
print("NameError")
f()
# here, "x" should remain a global
def f():
x.y: int
print(x)
f()

View File

@@ -0,0 +1,5 @@
False
1
(1, 2)
NameError
1

View File

@@ -0,0 +1,89 @@
try:
import uarray as array
except ImportError:
try:
import array
except ImportError:
print("SKIP")
raise SystemExit
a = array.array('B', [1, 2, 3])
print(a, len(a))
i = array.array('I', [1, 2, 3])
print(i, len(i))
print(a[0])
print(i[-1])
a = array.array('l', [-1])
print(len(a), a[0])
a1 = array.array('l', [1, 2, 3])
a2 = array.array('L', [1, 2, 3])
print(a2[1])
print(a1 == a2)
# Empty arrays
print(len(array.array('h')))
print(array.array('i'))
# bool operator acting on arrays
print(bool(array.array('i')))
print(bool(array.array('i', [1])))
# containment, with incorrect type
print('12' in array.array('B', b'12'))
print([] in array.array('B', b'12'))
# bad typecode
try:
array.array('X')
except ValueError:
print("ValueError")
# equality (CPython requires both sides are array)
print(bytes(array.array('b', [0x61, 0x62, 0x63])) == b'abc')
print(array.array('b', [0x61, 0x62, 0x63]) == b'abc')
print(array.array('B', [0x61, 0x62, 0x63]) == b'abc')
print(array.array('b', [0x61, 0x62, 0x63]) != b'abc')
print(array.array('b', [0x61, 0x62, 0x63]) == b'xyz')
print(array.array('b', [0x61, 0x62, 0x63]) != b'xyz')
print(b'abc' == array.array('b', [0x61, 0x62, 0x63]))
print(b'abc' == array.array('B', [0x61, 0x62, 0x63]))
print(b'abc' != array.array('b', [0x61, 0x62, 0x63]))
print(b'xyz' == array.array('b', [0x61, 0x62, 0x63]))
print(b'xyz' != array.array('b', [0x61, 0x62, 0x63]))
compatible_typecodes = []
for t in ["b", "h", "i", "l", "q"]:
compatible_typecodes.append((t, t))
compatible_typecodes.append((t, t.upper()))
for a, b in compatible_typecodes:
print(array.array(a, [1, 2]) == array.array(b, [1, 2]))
class X(array.array):
pass
print(bytes(X('b', [0x61, 0x62, 0x63])) == b'abc')
print(X('b', [0x61, 0x62, 0x63]) == b'abc')
print(X('b', [0x61, 0x62, 0x63]) != b'abc')
print(X('b', [0x61, 0x62, 0x63]) == array.array('b', [0x61, 0x62, 0x63]))
print(X('b', [0x61, 0x62, 0x63]) != array.array('b', [0x61, 0x62, 0x63]))
# other comparisons
for typecode in ["B", "H", "I", "L", "Q"]:
a = array.array(typecode, [1, 1])
print(a < a)
print(a <= a)
print(a > a)
print(a >= a)
al = array.array(typecode, [1, 0])
ab = array.array(typecode, [1, 2])
print(a < al)
print(a <= al)
print(a > al)
print(a >= al)
print(a < ab)
print(a <= ab)
print(a > ab)
print(a >= ab)

View File

@@ -0,0 +1,19 @@
# test array + array
try:
import uarray as array
except ImportError:
try:
import array
except ImportError:
print("SKIP")
raise SystemExit
a1 = array.array('I', [1])
a2 = array.array('I', [2])
print(a1 + a2)
a1 += array.array('I', [3, 4])
print(a1)
a1.extend(array.array('I', [5]))
print(a1)

View File

@@ -0,0 +1,23 @@
# test construction of array.array from different objects
try:
from uarray import array
except ImportError:
try:
from array import array
except ImportError:
print("SKIP")
raise SystemExit
# tuple, list
print(array('b', (1, 2)))
print(array('h', [1, 2]))
# raw copy from bytes, bytearray
print(array('h', b'22')) # should be byteorder-neutral
print(array('h', bytearray(2)))
print(array('i', bytearray(4)))
# convert from other arrays
print(array('H', array('b', [1, 2])))
print(array('b', array('I', [1, 2])))

View File

@@ -0,0 +1,11 @@
try:
from uarray import array
except ImportError:
try:
from array import array
except ImportError:
print("SKIP")
raise SystemExit
# construct from something with unknown length (requires generators)
print(array('i', (i for i in range(10))))

View File

@@ -0,0 +1,13 @@
# test construction of array.array from different objects
try:
from uarray import array
except ImportError:
try:
from array import array
except ImportError:
print("SKIP")
raise SystemExit
# raw copy from bytes, bytearray
print(array('h', b'12'))

View File

@@ -0,0 +1,25 @@
# test array types QqLl that require big-ints
try:
from uarray import array
except ImportError:
try:
from array import array
except ImportError:
print("SKIP")
raise SystemExit
print(array('L', [0, 2**32-1]))
print(array('l', [-2**31, 0, 2**31-1]))
print(array('q'))
print(array('Q'))
print(array('q', [0]))
print(array('Q', [0]))
print(array('q', [-2**63, -1, 0, 1, 2, 2**63-1]))
print(array('Q', [0, 1, 2, 2**64-1]))
print(bytes(array('q', [-1])))
print(bytes(array('Q', [2**64-1])))

View File

@@ -0,0 +1,31 @@
# test MicroPython-specific features of array.array
try:
import uarray as array
except ImportError:
try:
import array
except ImportError:
print("SKIP")
raise SystemExit
# arrays of objects
a = array.array('O')
a.append(1)
print(a[0])
# arrays of pointers
a = array.array('P')
a.append(1)
print(a[0])
# comparison between mismatching binary layouts is not implemented
typecodes = ["b", "h", "i", "l", "q", "P", "O", "S", "f", "d"]
for a in typecodes:
for b in typecodes:
if a == b and a not in ["f", "d"]:
continue
try:
array.array(a) == array.array(b)
print('FAIL')
except NotImplementedError:
pass

View File

@@ -0,0 +1,2 @@
1
1

View File

@@ -0,0 +1,11 @@
# test assignments
a = 1
print(a)
a = b = 2
print(a, b)
a = b = c = 3
print(a, b, c)

View File

@@ -0,0 +1,29 @@
(x := 4)
print(x)
if x := 2:
print(True)
print(x)
print(4, x := 5)
print(x)
x = 1
print(x, x := 5, x)
print(x)
def foo():
print("any", any((hit := i) % 5 == 3 and (hit % 2) == 0 for i in range(10)))
return hit
hit = 123
print(foo())
print(hit) # shouldn't be changed by foo
print("any", any((hit := i) % 5 == 3 and (hit % 2) == 0 for i in range(10)))
print(hit) # should be changed by above
print([((m := k + 1), k * m) for k in range(4)])
print(m)

View File

@@ -0,0 +1,14 @@
4
True
2
4 5
5
1 5 5
5
any True
8
123
any True
8
[(1, 0), (2, 2), (3, 6), (4, 12)]
4

View File

@@ -0,0 +1,16 @@
# test SyntaxError with := operator
def test(code):
try:
print(eval(code))
except SyntaxError:
print('SyntaxError')
test("x := 1")
test("((x, y) := 1)")
# these are currently all allowed in MicroPython, but not in CPython
test("([i := i + 1 for i in range(4)])")
test("([i := -1 for i, j in [(1, 2)]])")
test("([[(i := j) for i in range(2)] for j in range(2)])")
test("([[(j := i) for i in range(2)] for j in range(2)])")

View File

@@ -0,0 +1,6 @@
SyntaxError
SyntaxError
[1, 2, 3, 4]
[-1]
[[0, 0], [1, 1]]
[[0, 1], [0, 1]]

View File

@@ -0,0 +1,17 @@
# test basic await expression
# adapted from PEP0492
async def abinary(n):
print(n)
if n <= 0:
return 1
l = await abinary(n - 1)
r = await abinary(n - 1)
return l + 1 + r
o = abinary(4)
try:
while True:
o.send(None)
except StopIteration:
print('finished')

View File

@@ -0,0 +1,32 @@
4
3
2
1
0
0
1
0
0
2
1
0
0
1
0
0
3
2
1
0
0
1
0
0
2
1
0
0
1
0
0
finished

View File

@@ -0,0 +1,30 @@
# test await expression
try:
import usys as sys
except ImportError:
import sys
if sys.implementation.name == 'micropython':
# uPy allows normal generators to be awaitables
coroutine = lambda f: f
else:
import types
coroutine = types.coroutine
@coroutine
def wait(value):
print('wait value:', value)
msg = yield 'message from wait({})'.format(value)
print('wait got back:', msg)
return 10
async def f():
x = await wait(1)**2
print('x =', x)
coro = f()
print('return from send:', coro.send(None))
try:
coro.send('message from main')
except StopIteration:
print('got StopIteration')

View File

@@ -0,0 +1,5 @@
wait value: 1
return from send: message from wait(1)
wait got back: message from main
x = 100
got StopIteration

View File

@@ -0,0 +1,16 @@
# test async def
def dec(f):
print('decorator')
return f
# test definition with a decorator
@dec
async def foo():
print('foo')
coro = foo()
try:
coro.send(None)
except StopIteration:
print('StopIteration')

View File

@@ -0,0 +1,3 @@
decorator
foo
StopIteration

View File

@@ -0,0 +1,29 @@
# test basic async for execution
# example taken from PEP0492
class AsyncIteratorWrapper:
def __init__(self, obj):
print('init')
self._it = iter(obj)
def __aiter__(self):
print('aiter')
return self
async def __anext__(self):
print('anext')
try:
value = next(self._it)
except StopIteration:
raise StopAsyncIteration
return value
async def coro():
async for letter in AsyncIteratorWrapper('abc'):
print(letter)
o = coro()
try:
o.send(None)
except StopIteration:
print('finished')

View File

@@ -0,0 +1,10 @@
init
aiter
anext
a
anext
b
anext
c
anext
finished

View File

@@ -0,0 +1,50 @@
# test waiting within "async for" __anext__ function
try:
import usys as sys
except ImportError:
import sys
if sys.implementation.name == 'micropython':
# uPy allows normal generators to be awaitables
coroutine = lambda f: f
else:
import types
coroutine = types.coroutine
@coroutine
def f(x):
print('f start:', x)
yield x + 1
yield x + 2
return x + 3
class ARange:
def __init__(self, high):
print('init')
self.cur = 0
self.high = high
def __aiter__(self):
print('aiter')
return self
async def __anext__(self):
print('anext')
print('f returned:', await f(20))
if self.cur < self.high:
val = self.cur
self.cur += 1
return val
else:
raise StopAsyncIteration
async def coro():
async for x in ARange(4):
print('x', x)
o = coro()
try:
while True:
print('coro yielded:', o.send(None))
except StopIteration:
print('finished')

View File

@@ -0,0 +1,32 @@
init
aiter
anext
f start: 20
coro yielded: 21
coro yielded: 22
f returned: 23
x 0
anext
f start: 20
coro yielded: 21
coro yielded: 22
f returned: 23
x 1
anext
f start: 20
coro yielded: 21
coro yielded: 22
f returned: 23
x 2
anext
f start: 20
coro yielded: 21
coro yielded: 22
f returned: 23
x 3
anext
f start: 20
coro yielded: 21
coro yielded: 22
f returned: 23
finished

View File

@@ -0,0 +1,19 @@
# test syntax errors using async
try:
exec
except NameError:
print("SKIP")
raise SystemExit
def test_syntax(code):
try:
exec(code)
print("no SyntaxError")
except SyntaxError:
print("SyntaxError")
test_syntax("async for x in (): x")
test_syntax("async with x: x")

View File

@@ -0,0 +1,2 @@
SyntaxError
SyntaxError

View File

@@ -0,0 +1,39 @@
# test simple async with execution
class AContext:
async def __aenter__(self):
print('enter')
return 1
async def __aexit__(self, exc_type, exc, tb):
print('exit', exc_type, exc)
async def f():
async with AContext():
print('body')
o = f()
try:
o.send(None)
except StopIteration:
print('finished')
async def g():
async with AContext() as ac:
print(ac)
raise ValueError('error')
o = g()
try:
o.send(None)
except ValueError:
print('ValueError')
# test raising BaseException to make sure it is handled by the async-with
async def h():
async with AContext():
raise BaseException
o = h()
try:
o.send(None)
except BaseException:
print('BaseException')

View File

@@ -0,0 +1,11 @@
enter
body
exit None None
finished
enter
1
exit <class 'ValueError'> error
ValueError
enter
exit <class 'BaseException'>
BaseException

View File

@@ -0,0 +1,40 @@
# test waiting within async with enter/exit functions
try:
import usys as sys
except ImportError:
import sys
if sys.implementation.name == 'micropython':
# uPy allows normal generators to be awaitables
coroutine = lambda f: f
else:
import types
coroutine = types.coroutine
@coroutine
def f(x):
print('f start:', x)
yield x + 1
yield x + 2
return x + 3
class AContext:
async def __aenter__(self):
print('enter')
print('f returned:', await f(10))
async def __aexit__(self, exc_type, exc, tb):
print('exit', exc_type, exc)
print('f returned:', await f(20))
async def coro():
async with AContext():
print('body start')
print('body f returned:', await f(30))
print('body end')
o = coro()
try:
while True:
print('coro yielded:', o.send(None))
except StopIteration:
print('finished')

View File

@@ -0,0 +1,17 @@
enter
f start: 10
coro yielded: 11
coro yielded: 12
f returned: 13
body start
f start: 30
coro yielded: 31
coro yielded: 32
body f returned: 33
body end
exit None None
f start: 20
coro yielded: 21
coro yielded: 22
f returned: 23
finished

View File

@@ -0,0 +1,59 @@
# test async with, escaped by a break
class AContext:
async def __aenter__(self):
print('enter')
return 1
async def __aexit__(self, exc_type, exc, tb):
print('exit', exc_type, exc)
async def f1():
while 1:
async with AContext():
print('body')
break
print('no 1')
print('no 2')
o = f1()
try:
print(o.send(None))
except StopIteration:
print('finished')
async def f2():
while 1:
try:
async with AContext():
print('body')
break
print('no 1')
finally:
print('finally')
print('no 2')
o = f2()
try:
print(o.send(None))
except StopIteration:
print('finished')
async def f3():
while 1:
try:
try:
async with AContext():
print('body')
break
print('no 1')
finally:
print('finally inner')
finally:
print('finally outer')
print('no 2')
o = f3()
try:
print(o.send(None))
except StopIteration:
print('finished')

View File

@@ -0,0 +1,15 @@
enter
body
exit None None
finished
enter
body
exit None None
finally
finished
enter
body
exit None None
finally inner
finally outer
finished

View File

@@ -0,0 +1,50 @@
# test async with, escaped by a return
class AContext:
async def __aenter__(self):
print('enter')
return 1
async def __aexit__(self, exc_type, exc, tb):
print('exit', exc_type, exc)
async def f1():
async with AContext():
print('body')
return
o = f1()
try:
o.send(None)
except StopIteration:
print('finished')
async def f2():
try:
async with AContext():
print('body')
return
finally:
print('finally')
o = f2()
try:
o.send(None)
except StopIteration:
print('finished')
async def f3():
try:
try:
async with AContext():
print('body')
return
finally:
print('finally inner')
finally:
print('finally outer')
o = f3()
try:
o.send(None)
except StopIteration:
print('finished')

View File

@@ -0,0 +1,15 @@
enter
body
exit None None
finished
enter
body
exit None None
finally
finished
enter
body
exit None None
finally inner
finally outer
finished

View File

@@ -0,0 +1,22 @@
# test attrtuple
# we can't test this type directly so we use sys.implementation object
try:
import usys as sys
except ImportError:
import sys
t = sys.implementation
# It can be just a normal tuple on small ports
try:
t.name
except AttributeError:
print("SKIP")
raise SystemExit
# test printing of attrtuple
print(str(t).find("version=") > 0)
# test read attr
print(isinstance(t.name, str))

View File

@@ -0,0 +1,41 @@
# tests for bool objects
# basic logic
print(not False)
print(not True)
print(False and True)
print(False or True)
# unary operators
print(+True)
print(-True)
# comparison with itself
print(False == False)
print(False == True)
print(True == False)
print(True == True)
print(False != False)
print(False != True)
print(True != False)
print(True != True)
# comparison with integers
print(False == 0)
print(0 == False)
print(True == 1)
print(1 == True)
print(True == 2)
print(2 == True)
print(False != 0)
print(0 != False)
print(True != 1)
print(1 != True)
print(True != 2)
print(2 != True)
# unsupported unary op
try:
len(False)
except TypeError:
print('TypeError')

View File

@@ -0,0 +1,30 @@
# tests basics of bound methods
# uPy and CPython differ when printing a bound method, so just print the type
print(type(repr([].append)))
class A:
def f(self):
return 0
def g(self, a):
return a
def h(self, a, b, c, d, e, f):
return a + b + c + d + e + f
# bound method with no extra args
m = A().f
print(m())
# bound method with 1 extra arg
m = A().g
print(m(1))
# bound method with lots of extra args
m = A().h
print(m(1, 2, 3, 4, 5, 6))
# can't assign attributes to a bound method
try:
A().f.x = 1
except AttributeError:
print('AttributeError')

View File

@@ -0,0 +1,13 @@
while True:
break
for i in range(4):
print('one', i)
if i > 2:
break
print('two', i)
for i in [1, 2, 3, 4]:
if i == 3:
break
print(i)

View File

@@ -0,0 +1,6 @@
# test builtin abs
print(abs(False))
print(abs(True))
print(abs(1))
print(abs(-1))

View File

@@ -0,0 +1,13 @@
# test builtin abs
# bignum
print(abs(123456789012345678901234567890))
print(abs(-123456789012345678901234567890))
# edge cases for 32 and 64 bit archs (small int overflow when negating)
print(abs(-0x3fffffff - 1))
print(abs(-0x3fffffffffffffff - 1))
# edge case for nan-boxing with 47-bit small int
i = -0x3fffffffffff
print(abs(i - 1))

View File

@@ -0,0 +1,19 @@
# test builtin "all" and "any"
tests = (
(),
[],
[False],
[True],
[False, True],
[True, False],
[False, False],
[True, True],
range(10),
)
for test in tests:
print(all(test))
for test in tests:
print(any(test))

View File

@@ -0,0 +1,11 @@
# test builtin bin function
print(bin(1))
print(bin(-1))
print(bin(15))
print(bin(-15))
print(bin(12345))
print(bin(0b10101))
print(bin(0b10101010101010101010))

View File

@@ -0,0 +1,3 @@
# test builtin bin function
print(bin(12345678901234567890))

View File

@@ -0,0 +1,46 @@
# test builtin callable
# primitives should not be callable
print(callable(None))
print(callable(1))
print(callable([]))
print(callable("dfsd"))
# modules should not be callabe
try:
import usys as sys
except ImportError:
import sys
print(callable(sys))
# builtins should be callable
print(callable(callable))
# lambdas should be callable
print(callable(lambda:None))
# user defined functions should be callable
def f():
pass
print(callable(f))
# types should be callable, but not instances
class A:
pass
print(callable(A))
print(callable(A()))
# instances with __call__ method should be callable
class B:
def __call__(self):
pass
print(callable(B()))
# this checks internal use of callable when extracting members from an instance
class C:
def f(self):
return "A.f"
class D:
g = C() # g is a value and is not callable
print(callable(D().g))
print(D().g.f())

View File

@@ -0,0 +1,9 @@
# test builtin chr (whether or not we support unicode)
print(chr(65))
try:
chr(0x110000)
except ValueError:
print("ValueError")

View File

@@ -0,0 +1,45 @@
# test compile builtin
try:
compile
except NameError:
print("SKIP")
raise SystemExit
def test():
global x
c = compile("print(x)", "file", "exec")
try:
exec(c)
except NameError:
print("NameError")
# global variable for compiled code to access
x = 1
exec(c)
exec(c, {"x":2})
exec(c, {}, {"x":3})
# single/eval mode
exec(compile("if 1: 10 + 1\n", "file", "single"))
exec(compile("print(10 + 2)", "file", "single"))
print(eval(compile("10 + 3", "file", "eval")))
# bad mode
try:
compile('1', 'file', '')
except ValueError:
print("ValueError")
# exception within compiled code
try:
exec(compile('noexist', 'file', 'exec'))
except NameError:
print("NameError")
print(x) # check 'x' still exists as a global
test()

View File

@@ -0,0 +1,23 @@
# test builtin delattr
try:
delattr
except:
print("SKIP")
raise SystemExit
class A: pass
a = A()
a.x = 1
print(a.x)
delattr(a, 'x')
try:
a.x
except AttributeError:
print('AttributeError')
try:
delattr(a, 'x')
except AttributeError:
print('AttributeError')

View File

@@ -0,0 +1,41 @@
# test builtin dir
# dir of locals
print('__name__' in dir())
# dir of module
try:
import usys as sys
except ImportError:
import sys
print('version' in dir(sys))
# dir of type
print('append' in dir(list))
class Foo:
def __init__(self):
self.x = 1
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'))

View File

@@ -0,0 +1,15 @@
# test builtin divmod
print(divmod(0, 2))
print(divmod(3, 4))
print(divmod(20, 3))
try:
divmod(1, 0)
except ZeroDivisionError:
print("ZeroDivisionError")
try:
divmod('a', 'b')
except TypeError:
print("TypeError")

View File

@@ -0,0 +1,13 @@
# test builtin divmod
try:
divmod(1 << 65, 0)
except ZeroDivisionError:
print("ZeroDivisionError")
# bignum
l = (1 << 65) + 123
print(divmod(3, l))
print(divmod(l, 5))
print(divmod(l + 3, l))
print(divmod(l * 20, l + 2))

View File

@@ -0,0 +1,9 @@
# tests that .../Ellipsis exists
print(...)
print(Ellipsis)
print(... == Ellipsis)
# Test that Ellipsis can be hashed
print(type(hash(Ellipsis)))

View File

@@ -0,0 +1,23 @@
try:
enumerate
except:
print("SKIP")
raise SystemExit
print(list(enumerate([])))
print(list(enumerate([1, 2, 3])))
print(list(enumerate([1, 2, 3], 5)))
print(list(enumerate([1, 2, 3], -5)))
print(list(enumerate(range(100))))
# specifying args with keywords
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

View File

@@ -0,0 +1,19 @@
# builtin eval
try:
eval
except NameError:
print("SKIP")
raise SystemExit
eval('1 + 2')
eval('1 + 2\n')
eval('1 + 2\n\n#comment\n')
x = 4
eval('x')
eval('lambda x: x + 10')(-5)
y = 6
eval('lambda: y * 2')()

View File

@@ -0,0 +1,12 @@
# test builtin eval with a buffer (bytearray/memoryview) input
try:
eval
bytearray
memoryview
except:
print("SKIP")
raise SystemExit
print(eval(bytearray(b'1 + 1')))
print(eval(memoryview(b'2 + 2')))

View File

@@ -0,0 +1,12 @@
# test if eval raises SyntaxError
try:
eval
except NameError:
print("SKIP")
raise SystemExit
try:
print(eval("[1,,]"))
except SyntaxError:
print("SyntaxError")

View File

@@ -0,0 +1,40 @@
# test builtin exec
try:
exec
except NameError:
print("SKIP")
raise SystemExit
print(exec("def foo(): return 42"))
print(foo())
d = {}
exec("def bar(): return 84", d)
print(d["bar"]())
# passing None/dict as args to globals/locals
foo = 11
exec('print(foo)')
exec('print(foo)', None)
exec('print(foo)', {'foo':3}, None)
exec('print(foo)', None, {'foo':3})
exec('print(foo)', None, {'bar':3})
exec('print(foo)', {'bar':3}, locals())
try:
exec('print(foo)', {'bar':3}, None)
except NameError:
print('NameError')
# invalid arg passed to globals
try:
exec('print(1)', 'foo')
except TypeError:
print('TypeError')
# invalid arg passed to locals
try:
exec('print(1)', None, 123)
except TypeError:
print('TypeError')

View File

@@ -0,0 +1,12 @@
# test builtin exec with a buffer (bytearray/memoryview) input
try:
exec
bytearray
memoryview
except:
print("SKIP")
raise SystemExit
exec(bytearray(b'print(1)'))
exec(memoryview(b'print(2)'))

View File

@@ -0,0 +1,8 @@
try:
filter
except:
print("SKIP")
raise SystemExit
print(list(filter(lambda x: x & 1, range(-3, 4))))
print(list(filter(None, range(-3, 4))))

View File

@@ -0,0 +1,30 @@
class A:
var = 132
def __init__(self):
self.var2 = 34
def meth(self, i):
return 42 + i
a = A()
print(getattr(a, "var"))
print(getattr(a, "var2"))
print(getattr(a, "meth")(5))
print(getattr(a, "_none_such", 123))
print(getattr(list, "foo", 456))
print(getattr(a, "va" + "r2"))
# test a class that defines __getattr__ and may raise AttributeError
class B:
def __getattr__(self, attr):
if attr == "a":
return attr
else:
raise AttributeError
b = B()
print(getattr(b, "a"))
print(getattr(b, "a", "default"))
print(getattr(b, "b", "default"))

View File

@@ -0,0 +1,46 @@
class A:
var = 132
def __init__(self):
self.var2 = 34
def meth(self, i):
return 42 + i
a = A()
print(hasattr(a, "var"))
print(hasattr(a, "var2"))
print(hasattr(a, "meth"))
print(hasattr(a, "_none_such"))
print(hasattr(list, "foo"))
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"))
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')
except TypeError:
print('TypeError')
try:
hasattr(1, 123)
except TypeError:
print('TypeError')

View File

@@ -0,0 +1,50 @@
# test builtin hash function
print(hash(False))
print(hash(True))
print({():1}) # hash tuple
print({(1,):1}) # hash non-empty tuple
print(hash in {hash:1}) # hash function
try:
hash([])
except TypeError:
print("TypeError")
class A:
def __hash__(self):
return 123
def __repr__(self):
return "a instance"
print(hash(A()))
print({A():1})
# all user-classes have default __hash__
class B:
pass
hash(B())
# if __eq__ is defined then default __hash__ is not used
class C:
def __eq__(self, another):
return True
try:
hash(C())
except TypeError:
print("TypeError")
# __hash__ must return an int
class D:
def __hash__(self):
return None
try:
hash(D())
except TypeError:
print("TypeError")
# __hash__ returning a bool should be converted to an int
class E:
def __hash__(self):
return True
print(hash(E()))

View File

@@ -0,0 +1,7 @@
# test builtin hash function, on generators
def gen():
yield
print(type(hash(gen)))
print(type(hash(gen())))

View File

@@ -0,0 +1,13 @@
# test builtin hash function
print({1 << 66:1}) # hash big int
print({-(1 << 66):2}) # hash negative big int
# __hash__ returning a large number should be truncated
class F:
def __hash__(self):
return 1 << 70 | 1
print(hash(F()) != 0)
# this had a particular error with internal integer arithmetic of hash function
print(hash(6699999999999999999999999999999999999999999999999999999999999999999999) != 0)

View File

@@ -0,0 +1,17 @@
# test builtin help function
try:
help
except NameError:
print("SKIP")
raise SystemExit
help() # no args
help(help) # help for a function
help(int) # help for a class
help(1) # help for an instance
import micropython
help(micropython) # help for a module
help('modules') # list available modules
print('done') # so last bit of output is predictable

View File

@@ -0,0 +1,14 @@
########
object <function> is of type function
object <class 'int'> is of type type
from_bytes -- <classmethod>
to_bytes -- <function>
object 1 is of type int
from_bytes -- <classmethod>
to_bytes -- <function>
object <module 'micropython'> is of type module
__name__ -- micropython
const -- <function>
opt_level -- <function>
########
done

View File

@@ -0,0 +1,9 @@
# test builtin hex function
print(hex(1))
print(hex(-1))
print(hex(15))
print(hex(-15))
print(hex(12345))
print(hex(0x12345))

View File

@@ -0,0 +1,4 @@
# test builtin hex function
print(hex(12345678901234567890))
print(hex(0x12345678901234567890))

View File

@@ -0,0 +1,10 @@
print(id(1) == id(2))
print(id(None) == id(None))
# This can't be true per Python semantics, just CPython implementation detail
#print(id([]) == id([]))
l = [1, 2]
print(id(l) == id(l))
f = lambda:None
print(id(f) == id(f))

View File

@@ -0,0 +1,17 @@
# test builtin issubclass
class A:
pass
print(issubclass(A, A))
print(issubclass(A, (A,)))
try:
issubclass(A, 1)
except TypeError:
print('TypeError')
try:
issubclass('a', 1)
except TypeError:
print('TypeError')

View File

@@ -0,0 +1,13 @@
# builtin len
print(len(()))
print(len((1,)))
print(len((1, 2)))
print(len([]))
x = [1, 2, 3]
print(len(x))
f = len
print(f({}))
print(f({1:2, 3:4}))

View File

@@ -0,0 +1,13 @@
# test builtin locals()
x = 123
print(locals()['x'])
class A:
y = 1
def f(self):
pass
print('x' in locals())
print(locals()['y'])
print('f' in locals())

View File

@@ -0,0 +1,4 @@
print(list(map(lambda x: x & 1, range(-3, 4))))
print(list(map(abs, range(-3, 4))))
print(list(map(tuple, [[i] for i in range(-3, 4)])))
print(list(map(pow, range(4), range(4))))

View File

@@ -0,0 +1,47 @@
# test builtin min and max functions
try:
min
max
except:
print("SKIP")
raise SystemExit
print(min(0,1))
print(min(1,0))
print(min(0,-1))
print(min(-1,0))
print(max(0,1))
print(max(1,0))
print(max(0,-1))
print(max(-1,0))
print(min([1,2,4,0,-1,2]))
print(max([1,2,4,0,-1,2]))
# test with key function
lst = [2, 1, 3, 4]
print(min(lst, key=lambda x:x))
print(min(lst, key=lambda x:-x))
print(min(1, 2, 3, 4, key=lambda x:-x))
print(min(4, 3, 2, 1, key=lambda x:-x))
print(max(lst, key=lambda x:x))
print(max(lst, key=lambda x:-x))
print(max(1, 2, 3, 4, key=lambda x:-x))
print(max(4, 3, 2, 1, key=lambda x:-x))
# need at least 1 item in the iterable
try:
min([])
except ValueError:
print("ValueError")
# 'default' tests
print(min([1, 2, 3, 4, 5], default=-1))
print(min([], default=-1))
print(max([1, 2, 3, 4, 5], default=-1))
print(max([], default=-1))
# make sure it works with lazy iterables
# can't use Python generators here, as they're not supported
# byy native codegenerator.
print(min(enumerate([]), default=-10))

View File

@@ -0,0 +1,34 @@
# test next(iter, default)
try:
next(iter([]), 42)
except TypeError: # 2-argument version not supported
print('SKIP')
raise SystemExit
print(next(iter([]), 42))
print(next(iter(range(0)), 42))
print(next((x for x in [0] if x == 1), 43))
def gen():
yield 1
yield 2
g = gen()
print(next(g, 42))
print(next(g, 43))
print(next(g, 44))
class Gen:
def __init__(self):
self.b = False
def __next__(self):
if self.b:
raise StopIteration
self.b = True
return self.b
g = Gen()
print(next(g, 44))
print(next(g, 45))

View File

@@ -0,0 +1,9 @@
# test builtin oct function
print(oct(1))
print(oct(-1))
print(oct(15))
print(oct(-15))
print(oct(12345))
print(oct(0o12345))

View File

@@ -0,0 +1,4 @@
# test builtin oct function
print(oct(12345678901234567890))
print(oct(0o12345670123456701234))

View File

@@ -0,0 +1,28 @@
# test builtin ord (whether or not we support unicode)
print(ord('a'))
try:
ord('')
except TypeError:
print("TypeError")
# bytes also work in ord
print(ord(b'a'))
print(ord(b'\x00'))
print(ord(b'\x01'))
print(ord(b'\x7f'))
print(ord(b'\x80'))
print(ord(b'\xff'))
try:
ord(b'')
except TypeError:
print("TypeError")
# argument must be a string
try:
ord(1)
except TypeError:
print('TypeError')

View File

@@ -0,0 +1,36 @@
# test overriding builtins
import builtins
# override generic builtin
try:
builtins.abs = lambda x: x + 1
except AttributeError:
print("SKIP")
raise SystemExit
print(abs(1))
# __build_class__ is handled in a special way
orig_build_class = __build_class__
builtins.__build_class__ = lambda x, y: ('class', y)
class A:
pass
print(A)
builtins.__build_class__ = orig_build_class
# __import__ is handled in a special way
def custom_import(name, globals, locals, fromlist, level):
print('import', name, fromlist, level)
class M:
a = 1
b = 2
return M
builtins.__import__ = custom_import
__import__('A', None, None, None, 0)
import a
import a.b
from a import a
from a.b import a, b
from .a import a
from ..a import a, b

View File

@@ -0,0 +1,7 @@
# test builtin pow() with integral values
# 2 arg version
print(pow(0, 1))
print(pow(1, 0))
print(pow(-2, 3))
print(pow(3, 8))

View File

@@ -0,0 +1,30 @@
# test builtin pow() with integral values
# 3 arg version
try:
print(pow(3, 4, 7))
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))
except TypeError:
print("TypeError expected")
try:
print(pow(4, "y", 6))
except TypeError:
print("TypeError expected")
try:
print(pow(4, 5, "z"))
except TypeError:
print("TypeError expected")

View File

@@ -0,0 +1,22 @@
# test builtin pow() with integral values
# 3 arg version
try:
print(pow(3, 4, 7))
except NotImplementedError:
print("SKIP")
raise SystemExit
print(pow(555557, 1000002, 1000003))
# Tests for 3 arg pow with large values
# This value happens to be prime
x = 0xd48a1e2a099b1395895527112937a391d02d4a208bce5d74b281cf35a57362502726f79a632f063a83c0eba66196712d963aa7279ab8a504110a668c0fc38a7983c51e6ee7a85cae87097686ccdc359ee4bbf2c583bce524e3f7836bded1c771a4efcb25c09460a862fc98e18f7303df46aaeb34da46b0c4d61d5cd78350f3edb60e6bc4befa712a849
y = 0x3accf60bb1a5365e4250d1588eb0fe6cd81ad495e9063f90880229f2a625e98c59387238670936afb2cafc5b79448e4414d6cd5e9901aa845aa122db58ddd7b9f2b17414600a18c47494ed1f3d49d005a5
print(hex(pow(2, 200, x))) # Should not overflow, just 1 << 200
print(hex(pow(2, x-1, x))) # Should be 1, since x is prime
print(hex(pow(y, x-1, x))) # Should be 1, since x is prime
print(hex(pow(y, y-1, x))) # Should be a 'big value'
print(hex(pow(y, y-1, y))) # Should be a 'big value'

View File

@@ -0,0 +1,20 @@
# test builtin print function
print()
print(None)
print('')
print(1)
print(1, 2)
print(sep='')
print(sep='x')
print(end='')
print(end='x\n')
print(1, sep='')
print(1, end='')
print(1, sep='', end='')
print(1, 2, sep='')
print(1, 2, end='')
print(1, 2, sep='', end='')
print([{1:2}])

View File

@@ -0,0 +1,113 @@
# test builtin property
try:
property
except:
print("SKIP")
raise SystemExit
# create a property object explicitly
property()
property(1, 2, 3)
# use its accessor methods
p = property()
p.getter(1)
p.setter(2)
p.deleter(3)
# basic use as a decorator
class A:
def __init__(self, x):
self._x = x
@property
def x(self):
print("x get")
return self._x
a = A(1)
print(a.x)
try:
a.x = 2
except AttributeError:
print("AttributeError")
# explicit use within a class
class B:
def __init__(self, x):
self._x = x
def xget(self):
print("x get")
return self._x
def xset(self, value):
print("x set")
self._x = value
def xdel(self):
print("x del")
x = property(xget, xset, xdel)
b = B(3)
print(b.x)
b.x = 4
print(b.x)
del b.x
# full use as a decorator
class C:
def __init__(self, x):
self._x = x
@property
def x(self):
print("x get")
return self._x
@x.setter
def x(self, value):
print("x set")
self._x = value
@x.deleter
def x(self):
print("x del")
c = C(5)
print(c.x)
c.x = 6
print(c.x)
del c.x
# a property that has no get, set or del
class D:
prop = property()
d = D()
try:
d.prop
except AttributeError:
print('AttributeError')
try:
d.prop = 1
except AttributeError:
print('AttributeError')
try:
del d.prop
except AttributeError:
print('AttributeError')
# properties take keyword arguments
class E:
p = property(lambda self: 42, doc="This is truth.")
# 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))

View File

@@ -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

View File

@@ -0,0 +1,60 @@
# test builtin range type
# print
print(range(4))
# bool
print(bool(range(0)))
print(bool(range(10)))
# len
print(len(range(0)))
print(len(range(4)))
print(len(range(1, 4)))
print(len(range(1, 4, 2)))
print(len(range(1, 4, -1)))
print(len(range(4, 1, -1)))
print(len(range(4, 1, -2)))
# subscr
print(range(4)[0])
print(range(4)[1])
print(range(4)[-1])
# slice
print(range(4)[0:])
print(range(4)[1:])
print(range(4)[1:2])
print(range(4)[1:3])
print(range(4)[1::2])
print(range(4)[1:-2:2])
print(range(1, 4)[:])
print(range(1, 4)[0:])
print(range(1, 4)[1:])
print(range(1, 4)[:-1])
print(range(7, -2, -4)[:])
print(range(1, 100, 5)[5:15:3])
print(range(1, 100, 5)[15:5:-3])
print(range(100, 1, -5)[5:15:3])
print(range(100, 1, -5)[15:5:-3])
# 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)
except ValueError:
print("ValueError")
# bad unary op
try:
-range(1)
except TypeError:
print("TypeError")
# bad subscription (can't store)
try:
range(1)[0] = 1
except TypeError:
print("TypeError")

View File

@@ -0,0 +1,18 @@
# test attributes of builtin range type
try:
range(0).start
except AttributeError:
print("SKIP")
raise SystemExit
# attrs
print(range(1, 2, 3).start)
print(range(1, 2, 3).stop)
print(range(1, 2, 3).step)
# bad attr (can't store)
try:
range(4).start = 0
except AttributeError:
print('AttributeError')

View File

@@ -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')

View File

@@ -0,0 +1,44 @@
# test the builtin reverse() function
try:
reversed
except:
print("SKIP")
raise SystemExit
# list
print(list(reversed([])))
print(list(reversed([1])))
print(list(reversed([1, 2, 3])))
# tuple
print(list(reversed(())))
print(list(reversed((1, 2, 3))))
# string
for c in reversed('ab'):
print(c)
# bytes
for b in reversed(b'1234'):
print(b)
# range
for i in reversed(range(3)):
print(i)
# user object
class A:
def __init__(self):
pass
def __len__(self):
return 3
def __getitem__(self, pos):
return pos + 1
for a in reversed(A()):
print(a)
# user object with __reversed__
class B:
def __reversed__(self):
return [1, 2, 3]
print(reversed(B()))

View File

@@ -0,0 +1,8 @@
# test round() with integral values
tests = [
False, True,
0, 1, -1, 10
]
for t in tests:
print(round(t))

View File

@@ -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))

View File

@@ -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))

View File

@@ -0,0 +1,25 @@
class A:
var = 132
def __init__(self):
self.var2 = 34
a = A()
setattr(a, "var", 123)
setattr(a, "var2", 56)
print(a.var)
print(a.var2)
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')

View File

@@ -0,0 +1,11 @@
# test builtin slice
# print slice
class A:
def __getitem__(self, idx):
print(idx)
return idx
s = A()[1:2:3]
# check type
print(type(s) is slice)

View File

@@ -0,0 +1,16 @@
# test builtin sorted
try:
sorted
set
except:
print("SKIP")
raise SystemExit
print(sorted(set(range(100))))
print(sorted(set(range(100)), key=lambda x: x + 100*(x % 2)))
# need to use keyword argument
try:
sorted([], None)
except TypeError:
print("TypeError")

View File

@@ -0,0 +1,14 @@
# test builtin "sum"
tests = (
(),
[],
[0],
[1],
[0, 1, 2],
range(10),
)
for test in tests:
print(sum(test))
print(sum(test, -2))

View File

@@ -0,0 +1,31 @@
# test builtin type
print(type(int))
try:
type()
except TypeError:
print('TypeError')
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')

View File

@@ -0,0 +1,9 @@
try:
zip
set
except NameError:
print("SKIP")
raise SystemExit
print(list(zip()))
print(list(zip([1], set([2, 3]))))

Some files were not shown because too many files have changed in this diff Show More