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,27 @@
This directory contains tests for various functionality areas of MicroPython.
To run all stable tests, run "run-tests.py" script in this directory.
Tests of capabilities not supported on all platforms should be written
to check for the capability being present. If it is not, the test
should merely output 'SKIP' followed by the line terminator, and call
sys.exit() to raise SystemExit, instead of attempting to test the
missing capability. The testing framework (run-tests.py in this
directory, test_main.c in qemu_arm) recognizes this as a skipped test.
There are a few features for which this mechanism cannot be used to
condition a test. The run-tests.py script uses small scripts in the
feature_check directory to check whether each such feature is present,
and skips the relevant tests if not.
Tests are generally verified by running the test both in MicroPython and
in CPython and comparing the outputs. If the output differs the test fails
and the outputs are saved in a .out and a .exp file respectively.
For tests that cannot be run in CPython, for example because they use
the machine module, a .exp file can be provided next to the test's .py
file. A convenient way to generate that is to run the test, let it fail
(because CPython cannot run it) and then copy the .out file (but not
before checking it manually!)
When creating new tests, anything that relies on float support should go in the
float/ subdirectory. Anything that relies on import x, where x is not a built-in
module, should go in the import/ subdirectory.

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

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