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,12 @@
"""
categories: Modules,builtins
description: Second argument to next() is not implemented
cause: MicroPython is optimised for code space.
workaround: Instead of ``val = next(it, deflt)`` use::
try:
val = next(it)
except StopIteration:
val = deflt
"""
print(next(iter(range(0)), 42))

View File

@@ -0,0 +1,18 @@
"""
categories: Core,Classes
description: Special method __del__ not implemented for user-defined classes
cause: Unknown
workaround: Unknown
"""
import gc
class Foo:
def __del__(self):
print("__del__")
f = Foo()
del f
gc.collect()

View File

@@ -0,0 +1,19 @@
"""
categories: Core,Classes
description: Method Resolution Order (MRO) is not compliant with CPython
cause: Depth first non-exhaustive method resolution order
workaround: Avoid complex class hierarchies with multiple inheritance and complex method overrides. Keep in mind that many languages don't support multiple inheritance at all.
"""
class Foo:
def __str__(self):
return "Foo"
class C(tuple, Foo):
pass
t = C((1, 2, 3))
print(t)

View File

@@ -0,0 +1,32 @@
"""
categories: Core,Classes
description: When inheriting from multiple classes super() only calls one class
cause: See :ref:`cpydiff_core_class_mro`
workaround: See :ref:`cpydiff_core_class_mro`
"""
class A:
def __init__(self):
print("A.__init__")
class B(A):
def __init__(self):
print("B.__init__")
super().__init__()
class C(A):
def __init__(self):
print("C.__init__")
super().__init__()
class D(B, C):
def __init__(self):
print("D.__init__")
super().__init__()
D()

View File

@@ -0,0 +1,22 @@
"""
categories: Core,Classes
description: Calling super() getter property in subclass will return a property object, not the value
cause: Unknown
workaround: Unknown
"""
class A:
@property
def p(self):
return {"a": 10}
class AA(A):
@property
def p(self):
return super().p
a = AA()
print(a.p)

View File

@@ -0,0 +1,13 @@
"""
categories: Core
description: f-strings don't support concatenation with adjacent literals if the adjacent literals contain braces or are f-strings
cause: MicroPython is optimised for code space.
workaround: Use the + operator between literal strings when either or both are f-strings
"""
x, y = 1, 2
print("aa" f"{x}") # works
print(f"{x}" "ab") # works
print("a{}a" f"{x}") # fails
print(f"{x}" "a{}b") # fails
print(f"{x}" f"{y}") # fails

View File

@@ -0,0 +1,9 @@
"""
categories: Core
description: f-strings cannot support expressions that require parsing to resolve unbalanced nested braces and brackets
cause: MicroPython is optimised for code space.
workaround: Always use balanced braces and brackets in expressions inside f-strings
"""
print(f'{"hello { world"}')
print(f'{"hello ] world"}')

View File

@@ -0,0 +1,8 @@
"""
categories: Core
description: Raw f-strings are not supported
cause: MicroPython is optimised for code space.
workaround: Unknown
"""
rf"hello"

View File

@@ -0,0 +1,18 @@
"""
categories: Core
description: f-strings don't support the !r, !s, and !a conversions
cause: MicroPython is optimised for code space.
workaround: Use repr(), str(), and ascii() explictly.
"""
class X:
def __repr__(self):
return "repr"
def __str__(self):
return "str"
print(f"{X()!r}")
print(f"{X()!s}")

View File

@@ -0,0 +1,10 @@
"""
categories: Core,Functions
description: Error messages for methods may display unexpected argument counts
cause: MicroPython counts "self" as an argument.
workaround: Interpret error messages with the information above in mind.
"""
try:
[].append()
except Exception as e:
print(e)

View File

@@ -0,0 +1,13 @@
"""
categories: Core,Functions
description: Function objects do not have the ``__module__`` attribute
cause: MicroPython is optimized for reduced code size and RAM usage.
workaround: Use ``sys.modules[function.__globals__['__name__']]`` for non-builtin modules.
"""
def f():
pass
print(f.__module__)

View File

@@ -0,0 +1,14 @@
"""
categories: Core,Functions
description: User-defined attributes for functions are not supported
cause: MicroPython is highly optimized for memory usage.
workaround: Use external dictionary, e.g. ``FUNC_X[f] = 0``.
"""
def f():
pass
f.x = 0
print(f.x)

View File

@@ -0,0 +1,30 @@
"""
categories: Core,Generator
description: Context manager __exit__() not called in a generator which does not run to completion
cause: Unknown
workaround: Unknown
"""
class foo(object):
def __enter__(self):
print("Enter")
def __exit__(self, *args):
print("Exit")
def bar(x):
with foo():
while True:
x += 1
yield x
def func():
g = bar(0)
for _ in range(3):
print(next(g))
func()

View File

@@ -0,0 +1,9 @@
"""
categories: Core,import
description: __all__ is unsupported in __init__.py in MicroPython.
cause: Not implemented.
workaround: Manually import the sub-modules directly in __init__.py using ``from . import foo, bar``.
"""
from modules3 import *
foo.hello()

View File

@@ -0,0 +1,9 @@
"""
categories: Core,import
description: __path__ attribute of a package has a different type (single string instead of list of strings) in MicroPython
cause: MicroPython does't support namespace packages split across filesystem. Beyond that, MicroPython's import system is highly optimized for minimal memory usage.
workaround: Details of import handling is inherently implementation dependent. Don't rely on such details in portable applications.
"""
import modules
print(modules.__path__)

View File

@@ -0,0 +1,18 @@
"""
categories: Core,import
description: Failed to load modules are still registered as loaded
cause: To make module handling more efficient, it's not wrapped with exception handling.
workaround: Test modules before production use; during development, use ``del sys.modules["name"]``, or just soft or hard reset the board.
"""
import sys
try:
from modules import foo
except NameError as e:
print(e)
try:
from modules import foo
print("Should not get here")
except NameError as e:
print(e)

View File

@@ -0,0 +1,15 @@
"""
categories: Core,import
description: MicroPython does't support namespace packages split across filesystem.
cause: MicroPython's import system is highly optimized for simplicity, minimal memory usage, and minimal filesystem search overhead.
workaround: Don't install modules belonging to the same namespace package in different directories. For MicroPython, it's recommended to have at most 3-component module search paths: for your current application, per-user (writable), system-wide (non-writable).
"""
import sys
sys.path.append(sys.path[1] + "/modules")
sys.path.append(sys.path[1] + "/modules2")
import subpkg.foo
import subpkg.bar
print("Two modules of a split namespace package imported")

View File

@@ -0,0 +1,14 @@
"""
categories: Core,Runtime
description: Local variables aren't included in locals() result
cause: MicroPython doesn't maintain symbolic local environment, it is optimized to an array of slots. Thus, local variables can't be accessed by a name.
workaround: Unknown
"""
def test():
val = 2
print(locals())
test()

View File

@@ -0,0 +1,16 @@
"""
categories: Core,Runtime
description: Code running in eval() function doesn't have access to local variables
cause: MicroPython doesn't maintain symbolic local environment, it is optimized to an array of slots. Thus, local variables can't be accessed by a name. Effectively, ``eval(expr)`` in MicroPython is equivalent to ``eval(expr, globals(), globals())``.
workaround: Unknown
"""
val = 1
def test():
val = 2
print(val)
eval("print(val)")
test()

View File

@@ -0,0 +1,9 @@
"""
categories: Modules,array
description: Comparison between different typecodes not supported
cause: Code size
workaround: Compare individual elements
"""
import array
array.array("b", [1, 2]) == array.array("i", [1, 2])

View File

@@ -0,0 +1,10 @@
"""
categories: Modules,array
description: Overflow checking is not implemented
cause: MicroPython implements implicit truncation in order to reduce code size and execution time
workaround: If CPython compatibility is needed then mask the value explicitly
"""
import array
a = array.array("b", [257])
print(a)

View File

@@ -0,0 +1,2 @@
print("foo")
xxx

View File

@@ -0,0 +1 @@
__all__ = ["foo"]

View File

@@ -0,0 +1,2 @@
def hello():
print("hello")

View File

@@ -0,0 +1,9 @@
"""
categories: Modules,array
description: Looking for integer not implemented
cause: Unknown
workaround: Unknown
"""
import array
print(1 in array.array("B", b"12"))

View File

@@ -0,0 +1,11 @@
"""
categories: Modules,array
description: Array deletion not implemented
cause: Unknown
workaround: Unknown
"""
import array
a = array.array("b", (1, 2, 3))
del a[1]
print(a)

View File

@@ -0,0 +1,10 @@
"""
categories: Modules,array
description: Subscript with step != 1 is not yet implemented
cause: Unknown
workaround: Unknown
"""
import array
a = array.array("b", (1, 2, 3))
print(a[3:2:2])

View File

@@ -0,0 +1,10 @@
"""
categories: Modules,deque
description: Deque not implemented
cause: Unknown
workaround: Use regular lists. micropython-lib has implementation of collections.deque.
"""
import collections
D = collections.deque()
print(D)

View File

@@ -0,0 +1,15 @@
"""
categories: Modules,json
description: JSON module does not throw exception when object is not serialisable
cause: Unknown
workaround: Unknown
"""
import json
a = bytes(x for x in range(256))
try:
z = json.dumps(a)
x = json.loads(z)
print("Should not get here")
except TypeError:
print("TypeError")

View File

@@ -0,0 +1,17 @@
"""
categories: Modules,os
description: ``environ`` attribute is not implemented
cause: Unknown
workaround: Use ``getenv``, ``putenv`` and ``unsetenv``
"""
import os
try:
print(os.environ.get("NEW_VARIABLE"))
os.environ["NEW_VARIABLE"] = "VALUE"
print(os.environ["NEW_VARIABLE"])
except AttributeError:
print("should not get here")
print(os.getenv("NEW_VARIABLE"))
os.putenv("NEW_VARIABLE", "VALUE")
print(os.getenv("NEW_VARIABLE"))

View File

@@ -0,0 +1,11 @@
"""
categories: Modules,os
description: ``getenv`` returns actual value instead of cached value
cause: The ``environ`` attribute is not implemented
workaround: Unknown
"""
import os
print(os.getenv("NEW_VARIABLE"))
os.putenv("NEW_VARIABLE", "VALUE")
print(os.getenv("NEW_VARIABLE"))

View File

@@ -0,0 +1,14 @@
"""
categories: Modules,os
description: ``getenv`` only allows one argument
cause: Unknown
workaround: Test that the return value is ``None``
"""
import os
try:
print(os.getenv("NEW_VARIABLE", "DEFAULT"))
except TypeError:
print("should not get here")
# this assumes NEW_VARIABLE is never an empty variable
print(os.getenv("NEW_VARIABLE") or "DEFAULT")

View File

@@ -0,0 +1,12 @@
"""
categories: Modules,random
description: ``getrandbits`` method can only return a maximum of 32 bits at a time.
cause: PRNG's internal state is only 32bits so it can only return a maximum of 32 bits of data at a time.
workaround: If you need a number that has more than 32 bits then utilize the random module from micropython-lib.
"""
import random
x = random.getrandbits(64)
print("{}".format(x))

View File

@@ -0,0 +1,12 @@
"""
categories: Modules,random
description: ``randint`` method can only return an integer that is at most the native word size.
cause: PRNG is only able to generate 32 bits of state at a time. The result is then cast into a native sized int instead of a full int object.
workaround: If you need integers larger than native wordsize use the random module from micropython-lib.
"""
import random
x = random.randint(2**128 - 1, 2**128)
print("x={}".format(x))

View File

@@ -0,0 +1,13 @@
"""
categories: Modules,struct
description: Struct pack with too few args, not checked by uPy
cause: Unknown
workaround: Unknown
"""
import struct
try:
print(struct.pack("bb", 1))
print("Should not get here")
except:
print("struct.error")

View File

@@ -0,0 +1,13 @@
"""
categories: Modules,struct
description: Struct pack with too many args, not checked by uPy
cause: Unknown
workaround: Unknown
"""
import struct
try:
print(struct.pack("bb", 1, 2, 3))
print("Should not get here")
except:
print("struct.error")

View File

@@ -0,0 +1,13 @@
"""
categories: Modules,struct
description: Struct pack with whitespace in format, whitespace ignored by CPython, error on uPy
cause: MicroPython is optimised for code size.
workaround: Don't use spaces in format strings.
"""
import struct
try:
print(struct.pack("b b", 1, 2))
print("Should have worked")
except:
print("struct.error")

View File

@@ -0,0 +1,10 @@
"""
categories: Modules,sys
description: Overriding sys.stdin, sys.stdout and sys.stderr not possible
cause: They are stored in read-only memory.
workaround: Unknown
"""
import sys
sys.stdin = None
print(sys.stdin)

View File

@@ -0,0 +1,23 @@
"""
categories: Syntax
description: Argument unpacking does not work if the argument being unpacked is the nth or greater argument where n is the number of bits in an MP_SMALL_INT.
cause: The implementation uses an MP_SMALL_INT to flag args that need to be unpacked.
workaround: Use fewer arguments.
"""
def example(*args):
print(len(args))
MORE = ["a", "b", "c"]
# fmt: off
example(
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
*MORE,
)
# fmt: on

View File

@@ -0,0 +1,7 @@
"""
categories: Syntax,Operators
description: MicroPython allows using := to assign to the variable of a comprehension, CPython raises a SyntaxError.
cause: MicroPython is optimised for code size and doesn't check this case.
workaround: Do not rely on this behaviour if writing CPython compatible code.
"""
print([i := -1 for i in range(4)])

View File

@@ -0,0 +1,18 @@
"""
categories: Syntax,Spaces
description: uPy requires spaces between literal numbers and keywords, CPy doesn't
cause: Unknown
workaround: Unknown
"""
try:
print(eval("1and 0"))
except SyntaxError:
print("Should have worked")
try:
print(eval("1or 0"))
except SyntaxError:
print("Should have worked")
try:
print(eval("1if 1else 0"))
except SyntaxError:
print("Should have worked")

View File

@@ -0,0 +1,7 @@
"""
categories: Syntax,Unicode
description: Unicode name escapes are not implemented
cause: Unknown
workaround: Unknown
"""
print("\N{LATIN SMALL LETTER A}")

View File

@@ -0,0 +1,9 @@
"""
categories: Types,bytearray
description: Array slice assignment with unsupported RHS
cause: Unknown
workaround: Unknown
"""
b = bytearray(4)
b[0:1] = [1, 2]
print(b)

View File

@@ -0,0 +1,7 @@
"""
categories: Types,bytes
description: bytes objects support .format() method
cause: MicroPython strives to be a more regular implementation, so if both `str` and `bytes` support ``__mod__()`` (the % operator), it makes sense to support ``format()`` for both too. Support for ``__mod__`` can also be compiled out, which leaves only ``format()`` for bytes formatting.
workaround: If you are interested in CPython compatibility, don't use ``.format()`` on bytes objects.
"""
print(b"{}".format(1))

View File

@@ -0,0 +1,7 @@
"""
categories: Types,bytes
description: bytes() with keywords not implemented
cause: Unknown
workaround: Pass the encoding as a positional parameter, e.g. ``print(bytes('abc', 'utf-8'))``
"""
print(bytes("abc", encoding="utf8"))

View File

@@ -0,0 +1,7 @@
"""
categories: Types,bytes
description: Bytes subscription with step != 1 not implemented
cause: MicroPython is highly optimized for memory usage.
workaround: Use explicit loop for this very rare operation.
"""
print(b"123"[0:3:2])

View File

@@ -0,0 +1,7 @@
"""
categories: Types,dict
description: Dictionary keys view does not behave as a set.
cause: Not implemented.
workaround: Explicitly convert keys to a set before using set operations.
"""
print({1: 2, 3: 4}.keys() & {1})

View File

@@ -0,0 +1,9 @@
"""
categories: Types,Exception
description: All exceptions have readable ``value`` and ``errno`` attributes, not just ``StopIteration`` and ``OSError``.
cause: MicroPython is optimised to reduce code size.
workaround: Only use ``value`` on ``StopIteration`` exceptions, and ``errno`` on ``OSError`` exceptions. Do not use or rely on these attributes on other exceptions.
"""
e = Exception(1)
print(e.value)
print(e.errno)

View File

@@ -0,0 +1,10 @@
"""
categories: Types,Exception
description: Exception chaining not implemented
cause: Unknown
workaround: Unknown
"""
try:
raise TypeError
except TypeError:
raise ValueError

View File

@@ -0,0 +1,9 @@
"""
categories: Types,Exception
description: User-defined attributes for builtin exceptions are not supported
cause: MicroPython is highly optimized for memory usage.
workaround: Use user-defined exception subclasses.
"""
e = Exception()
e.x = 0
print(e.x)

View File

@@ -0,0 +1,12 @@
"""
categories: Types,Exception
description: Exception in while loop condition may have unexpected line number
cause: Condition checks are optimized to happen at the end of loop body, and that line number is reported.
workaround: Unknown
"""
l = ["-foo", "-bar"]
i = 0
while l[i][0] == "-":
print("iter")
i += 1

View File

@@ -0,0 +1,18 @@
"""
categories: Types,Exception
description: Exception.__init__ method does not exist.
cause: Subclassing native classes is not fully supported in MicroPython.
workaround: Call using ``super()`` instead::
class A(Exception):
def __init__(self):
super().__init__()
"""
class A(Exception):
def __init__(self):
Exception.__init__(self)
a = A()

View File

@@ -0,0 +1,7 @@
"""
categories: Types,float
description: uPy and CPython outputs formats may differ
cause: Unknown
workaround: Unknown
"""
print("%.1g" % -9.9)

View File

@@ -0,0 +1,9 @@
"""
categories: Types,int
description: ``bit_length`` method doesn't exist.
cause: bit_length method is not implemented.
workaround: Avoid using this method on MicroPython.
"""
x = 255
print("{} is {} bits long.".format(x, x.bit_length()))

View File

@@ -0,0 +1,14 @@
"""
categories: Types,int
description: No int conversion for int-derived types available
cause: Unknown
workaround: Avoid subclassing builtin types unless really needed. Prefer https://en.wikipedia.org/wiki/Composition_over_inheritance .
"""
class A(int):
__add__ = lambda self, other: A(int(self) + other)
a = A(42)
print(a + a)

View File

@@ -0,0 +1,9 @@
"""
categories: Types,list
description: List delete with step != 1 not implemented
cause: Unknown
workaround: Use explicit loop for this rare operation.
"""
l = [1, 2, 3, 4]
del l[0:4:2]
print(l)

View File

@@ -0,0 +1,9 @@
"""
categories: Types,list
description: List slice-store with non-iterable on RHS is not implemented
cause: RHS is restricted to be a tuple or list
workaround: Use ``list(<iter>)`` on RHS to convert the iterable to a list
"""
l = [10, 20]
l[0:1] = range(4)
print(l)

View File

@@ -0,0 +1,9 @@
"""
categories: Types,list
description: List store with step != 1 not implemented
cause: Unknown
workaround: Use explicit loop for this rare operation.
"""
l = [1, 2, 3, 4]
l[0:4:2] = [5, 6]
print(l)

View File

@@ -0,0 +1,7 @@
"""
categories: Types,str
description: Start/end indices such as str.endswith(s, start) not implemented
cause: Unknown
workaround: Unknown
"""
print("abc".endswith("c", 1))

View File

@@ -0,0 +1,7 @@
"""
categories: Types,str
description: Attributes/subscr not implemented
cause: Unknown
workaround: Unknown
"""
print("{a[0]}".format(a=[1, 2]))

View File

@@ -0,0 +1,7 @@
"""
categories: Types,str
description: str(...) with keywords not implemented
cause: Unknown
workaround: Input the encoding format directly. eg ``print(bytes('abc', 'utf-8'))``
"""
print(str(b"abc", encoding="utf8"))

View File

@@ -0,0 +1,7 @@
"""
categories: Types,str
description: str.ljust() and str.rjust() not implemented
cause: MicroPython is highly optimized for memory usage. Easy workarounds available.
workaround: Instead of ``s.ljust(10)`` use ``"%-10s" % s``, instead of ``s.rjust(10)`` use ``"% 10s" % s``. Alternatively, ``"{:<10}".format(s)`` or ``"{:>10}".format(s)``.
"""
print("abc".ljust(10))

View File

@@ -0,0 +1,7 @@
"""
categories: Types,str
description: None as first argument for rsplit such as str.rsplit(None, n) not implemented
cause: Unknown
workaround: Unknown
"""
print("a a a".rsplit(None, 1))

View File

@@ -0,0 +1,7 @@
"""
categories: Types,str
description: Subscript with step != 1 is not yet implemented
cause: Unknown
workaround: Unknown
"""
print("abcdefghi"[0:9:2])

View File

@@ -0,0 +1,7 @@
"""
categories: Types,tuple
description: Tuple load with step != 1 not implemented
cause: Unknown
workaround: Unknown
"""
print((1, 2, 3, 4)[0:4:2])