These all require hardware connections, so live in a different directory.
Except for the IRQ_BREAK test of ESP32 devices a single UART with loopback
is sufficient.
General:
SAMD21: Due to the limited flash size only SAMD21 devices with external
flash support uart.irq().
IRQ_BREAK:
ESP32 needs different UART devices for creating and sensing a break.
Lacking a second UART the test is skipped for ESP32S2 and ESP32C3. RP2
does not pass the test reliable at 115200 baud, reason to be found.
Thus the upper limit is set to 57600 Baud.
Coverage:
esp32 pass when different UART devices are used.
rp2 pass up to 57600 baud
IRQ_RX:
SAMD21: Being a slow device it needs data to be sent byte-by-byte at
9600 baud, since the IRQ callback is scheduled delayed and then the
flags do not match any more. The data matches since it is queued in
the FIFO resp. ringbuffer.
CC3200: The test cannot be performed since no calls are accepted in the
IRQ handler like u.read(). Skipped.
Coverage:
cc3200 fail due to major differences in the implementation.
esp32 pass
nrf pass
renesas-ra pass
samd pass see the notes.
stm32 pass
IRQ_RXIDLE:
STM32: With PyBoard the IRQ is called several times, but only once with
the flag IRQ_RXIDLE set.
Coverage:
esp32 pass
mimxrt pass
renesas-ra pass
rp2 pass
samd pass for both SAMD21 and SAMD51
stm32 fail. see notes.
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: robert-hh <robert@hammelrath.com>
The test checks whether the message created by the IRQ handler appears
about at the end of the data sent by UART.
Supported MCUs resp. boards:
- RP2040
- Teensy 4.x
- Adafruit ItsyBitsy M0
- Adafruit ItsyBitsy M4
- NRF52 (Arduino Nano Connect 33 BLE)
Signed-off-by: Damien George <damien@micropython.org>
Currently, the qemu-arm (and qemu-riscv) port has two build modes:
- a simple test that executes a Python string; and
- a full test that uses tinytest to embed all tests within the firmware,
then executes that and captures the output.
This is very different to all the other ports. A difficulty with using
tinytest is that with the large number of tests the firmware overflows its
virtual flash size. It's also hard to run tests via .mpy files and with
the native emitter. Being different to the other ports also means an extra
burden on maintenance.
This commit reworks the qemu-arm port so that it has a single build target
that creates a standard firmware which has a REPL. When run under
qemu-system-arm, the REPL acts like any other bare-metal port, complete
with soft reset (use machine.reset() to turn it off and exit
qemu-system-arm).
This approach gives many benefits:
- allows playing with a REPL without hardware;
- allows running the test suite as it would on a bare-metal board, by
making qemu-system-arm redirect the UART serial of the virtual device to
a /dev/pts/xx file, and then running run-tests.py against that serial
device;
- skipping tests is now done via the logic in `run-tests.py` and no longer
needs multiple places to define which tests to skip
(`tools/tinytest-codegen.py`, `ports/qemu-arm/tests_profile.txt` and also
`tests/run-tests.py`);
- allows testing/using mpremote with the qemu-arm port.
Eventually the qemu-riscv port would have a similar change.
Prior to this commit the test results were:
743 tests ok. (121 skipped)
With this commit the test results are:
753 tests performed (22673 individual testcases)
753 tests passed
138 tests skipped
More tests are skipped because more are included in the run. But overall
more tests pass.
Signed-off-by: Damien George <damien@micropython.org>
Skip whitespace characters between pairs of hex numbers.
This makes `bytes.fromhex()` compatible with cpython.
Includes simple test in `tests/basic/builtin_str_hex.py`.
Signed-off-by: Glenn Moloney <glenn.moloney@gmail.com>
Update to the test added in 1e98c4cb75,
changes the SPI pins for ESP32-C3 (IO 18 and 19 are the native USB pins).
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Necessary to pass CI when testing the V2 preview APIs.
Also adds an extra coverage test for the legacy stackctrl API, to maintain
coverage and check for any regression.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Based on machine_i2s_rate, allows testing basic SPI functionality and
timings.
Implemented and confirmed working for rp2, esp32, and pyboard.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
The `sslcontext_server_client_ciphers.py` test was using stat to test for
the .der files after it already tried to open them for reading. That is
now fixed. And `sslcontext_server_client.py` is adjusted to use the same
pattern for skipping the test.
Signed-off-by: Damien George <damien@micropython.org>
Install the mingw variant of Python since it behaves more like a 'real'
Windows CPython than the msys2 variant: os.name == 'nt', not 'posix'. Note
that os.sep is still '/' though so we don't actually need to skip the
import_file test. This way one single Python version can be used both for
running run-tests.py and getting the expected test output.
Signed-off-by: stijn <stijn@ignitron.net>
This fixes various null dereferencing and out-of-bounds access because
super_attr assumes the held obj is effectively an object of the held type,
which is now verified.
Fixes issue #12830.
Signed-off-by: stijn <stijn@ignitron.net>
This adds a CPython diff that explains why calling `super().__init__()` is
required in MicroPython when subclassing a native type (because `__new__`
and `__init__` are not separate functions).
Signed-off-by: David Lechner <david@pybricks.com>
When subclassing a native type, calling native members in `__init__` before
`super().__init__()` has been called could cause a crash. In this
situation, `self` in `mp_convert_member_lookup` is the
`native_base_init_wrapper_obj`. The check added in this commit ensures
that an `AttributeError` is raised before this happens, which is consistent
with other failed lookups.
Also fix a typo in a related comment.
Signed-off-by: Laurens Valk <laurens@pybricks.com>
This adds a separate `AdvancedTimer` class that demonstrates a few more
advanced concepts usch as custom handlers for printing and attributes.
Signed-off-by: Laurens Valk <laurens@pybricks.com>
Updates rp2 port to always resume from idle within 1ms max.
When rp2 port went tickless the behaviour of machine.idle() changed as
there is no longer a tick interrupt to wake it up every millisecond. On a
quiet system it would now block indefinitely. No other port does this.
See parent commit for justification of why this change is useful.
Also adds a test case that fails without this change.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Before the fix in parent commit, some of these tests hung indefinitely.
After, they seem to consistently pass.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Explicitly yield each time a thread mutex is unlocked.
Key to understanding this bug is that Python threads run at equal RTOS
priority, and although ESP-IDF FreeRTOS (and I think vanilla FreeRTOS)
scheduler will round-robin equal priority tasks in the ready state it does
not make a similar guarantee for tasks moving between ready and waiting.
The pathological case of this bug is when one Python thread task is busy
(i.e. never blocks) it will hog the CPU more than expected, sometimes for
an unbounded amount of time. This happens even though it periodically
unlocks the GIL to allow another task to run.
Assume T1 is busy and T2 is blocked waiting for the GIL. T1 is executing
and hits a condition to yield execution:
1. T1 calls MP_THREAD_GIL_EXIT
2. FreeRTOS sees T2 is waiting for the GIL and moves it to the Ready list
(but does not preempt, as T2 is same priority, so T1 keeps running).
3. T1 immediately calls MP_THREAD_GIL_ENTER and re-takes the GIL.
4. Pre-emptive context switch happens, T2 wakes up, sees GIL is not
available, and goes on the waiting list for the GIL again.
To break this cycle step 4 must happen before step 3, but this may be a
very narrow window of time so it may not happen regularly - and
quantisation of the timing of the tick interrupt to trigger a context
switch may mean it never happens.
Yielding at the end of step 2 maximises the chance for another task to run.
Adds a test that fails on esp32 before this fix and passes afterwards.
Fixes issue #15423.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Fixes various null dereferencing, out-of-bounds memory accesses and
`assert(0)` failures in the case of an invalid `uctypes` descriptor.
By design `uctypes` can crash because it accesses arbitrary memory, but at
least describing the descriptor layout should be forced to be correct and
not crash.
Fixes issue #12702.
Signed-off-by: stijn <stijn@ignitron.net>
Fixes use-after-free when accessing the database after it is closed with
`btree_close`. `btree_close` always succeeds when called with an
already-closed database.
The new test checks that operations that access the underlying database
(get, set, flush, seq) fail with a `ValueError` when the btree is already
closed. It also checks that closing and printing the btree succeed when
the btree is already closed.
Fixes issue #12543.
Signed-off-by: Michael Vornovitsky <michaelvornovitskiy@outlook.com>
This commit makes it so that PyProxy objects are reused (on the JavaScript
side) when they correspond to an existing Python object that is the same
object.
For example, proxying the same Python function to JavaScript, the same
PyProxy instance is now used. This means that if `foo` is a Python
function then accessing it on the JavaScript side such as
`api.globals().get("foo")` has the property that:
api.globals().get("foo") === api.globals().get("foo")
Prior to this commit the above was not true because new PyProxy instances
were created each time `foo` was accessed.
Signed-off-by: Damien George <damien@micropython.org>
Follow up to 2e852522b1: instead of having
.exp files for the get_event_loop tests, tweak them so they are compatible
with CPython 3.12. This requires calling `asyncio.set_event_loop()` so
there is an active event loop and `asyncio.get_event_loop()` succeeds
without a warning.
Signed-off-by: Damien George <damien@micropython.org>
A target may have enough RAM to run the n=433 test but then run out of RAM
on the n=432 test. So allow the test to skip on the n=432 case before it
prints any output.
Signed-off-by: Damien George <damien@micropython.org>
Because the main thread executes `thread_entry()` it means there's an
additional one added to `count`, so the test must wait for the count to
reach `n_thread + 1`.
Signed-off-by: Damien George <damien@micropython.org>
Before this change, long/mpz ints propagated into all future calculations,
even if their value could fit in a small-int object. With this change, the
result of a big-int binary op will now be converted to a small-int object
if the value fits in a small-int.
For example, a relatively common operation like `x = a * b // c` where
a,b,c all small ints would always result in a long/mpz int, even if it
didn't need to, and then this would impact all future calculations with
x.
This adds +24 bytes on PYBV11 but avoids heap allocations and potential
surprises (e.g. `big-big` is now a small `0`, and can safely be accessed
with MP_OBJ_SMALL_INT_VALUE).
Performance tests are unchanged on PYBV10, except for `bm_pidigits.py`
which makes heavy use of big-ints and gains about 8% in speed.
Unix coverage tests have been updated to cover mpz code that is now
unreachable by normal Python code (removing the unreachable code would lead
to some surprising gaps in the internal C functions and the functionality
may be needed in the future, so it is kept because it has minimal
overhead).
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
In JavaScript when accessing an attribute such as `obj.attr` a value of
`undefined` is returned if the attribute does not exist. This is unlike
Python semantics where an `AttributeError` is raised. Furthermore, in some
cases in JavaScript (eg a Proxy instance) `attr in obj` can return false
yet `obj.attr` is still valid and returns something other than `undefined`.
So the source of truth for whether a JavaScript attribute exists is to just
right away attempt `obj.attr`.
To more closely match these JavaScript semantics when proxying a JavaScript
object through to Python, change the attribute lookup logic on a `JsProxy`
so that it immediately attempts `obj.attr` instead of first testing if the
attribute exists via `attr in obj`.
This allows JavaScript objects which dynamically create attributes to work
correctly on the Python side, with both `obj.attr` and `obj["attr"]`. Note
that `obj["attr"]` already works in all cases because it immediately does
the subscript access without first testing if the attribute exists.
As a benefit, this new behaviour matches the Pyodide behaviour.
Signed-off-by: Damien George <damien@micropython.org>
Follow-up to a84c7a0ed9, this commit works most of the time but has an
intermittent bug where USB doesn't resume as expected after waking from
light sleep.
Turns out waking calls clocks_init() which will re-initialise the USB PLL.
Most of the time this is OK but occasionally it seems like the clock
glitches the USB peripheral and it stops working until the next hard reset.
Adds a machine.lightsleep() test that consistently hangs in the first
two dozen iterations on rp2 without this fix. Passed over 100 times in a
row with this fix.
The test is currently rp2-only as it seems similar lightsleep USB issues
exist on other ports (both pyboard and ESP32-S3 native USB don't send any
data to the host after waking, until they receive something from the host
first.)
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
mp_thread_begin_atomic_section() is expected to be recursive (i.e. for
nested machine.disable_irq() calls, or if Python code calls disable_irq()
and then the Python runtime calls mp_handle_pending() which also enters an
atomic section to check the scheduler state).
On rp2 when not using core1 the atomic sections are recursive.
However when core1 was active (i.e. _thread) then there was a bug that
caused the core to live-lock if an atomic section recursed.
Adds a test case specifically for mutual exclusion and recursive atomic
sections when using two threads. Without this fix the test immediately
hangs on rp2.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Fixes and improvements to `int.to_bytes()` are:
- No longer overflows if byte size is 0 (closes#13041).
- Raises OverflowError in any case where number won't fit into byte length
(now matches CPython, previously MicroPython would return a truncated
bytes object).
- Document that `micropython int.to_bytes()` doesn't implement the optional
signed kwarg, but will behave as if `signed=True` when the integer is
negative (this is the current behaviour). Add tests for this also.
Requires changes for small ints, MPZ large ints, and "long long" large
ints.
Adds a new set of unit tests for ints between 32 and 64 bits to increase
coverage of "long long" large ints, which are otherwise untested.
Tested on unix port (64 bit small ints, MPZ long ints) and Zephyr STM32WB
board (32 bit small ints, long long large ints).
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
The code generating the entry to the finally handler of an async-with
statement was simply wrong for the case of the native emitter. Among other
things the layout of the stack was incorrect.
This is fixed by this commit. The setup of the async-with finally handler
is now put in a dedicated emit function, for both the bytecode and native
emitters to implement in their own way (the bytecode emitter is unchanged,
just factored to a function).
With this fix all of the async-with tests now work when using the native
emitter.
Signed-off-by: Damien George <damien@micropython.org>
A value thrown/injected into a native generator needs to be stored in a
dedicated variable outside `nlr_buf_t`, following the `inject_exc` variable
in `py/vm.c`.
Signed-off-by: Damien George <damien@micropython.org>
Otherwise GC stays disabled (not re-enabled by soft reset) and later test
runs fail with MemoryError.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
This allows increasing the Python recursion depth if needed.
Also increase the default to 2k words. There is enough RAM in the
browser/node context for this to be increased, and having a larger pystack
allows more complex code to run without hitting the limit.
Signed-off-by: Damien George <damien@micropython.org>
In the webassembly port there is no asyncio run loop running at the top
level. Instead the Python asyncio run loop is scheduled through setTimeout
and run by the outer JavaScript event loop. Because tasks can become
runable from an external (to Python) event (eg a JavaScript callback), the
run loop must be scheduled whenever a task is pushed to the asyncio task
queue, otherwise tasks may be waiting forever on the queue.
Signed-off-by: Damien George <damien@micropython.org>
This change allows doing a top-level await on an asyncio primitive like
Task and Event.
This feature enables a better interaction and synchronisation between
JavaScript and Python, because `api.runPythonAsync` can now be used (called
from JavaScript) to await on the completion of asyncio primitives.
Signed-off-by: Damien George <damien@micropython.org>
This adds a QEMU-based bare metal RISC-V 32 bits port. For the time being
only QEMU's "virt" 32 bits board is supported, using the ilp32 ABI and the
RV32IMC architecture.
The top-level README and the run-tests.py files are updated for this new
port.
Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
If the socket timeout is 0 then a failed socket.connect() raises
EINPROGRESS (which is what the lwIP bindings already did), but if the
socket timeout is non-zero then a failed socket.connect() should raise
ETIMEDOUT. The latter is fixed in this commit.
A test is added for these timeout cases.
Signed-off-by: Damien George <damien@micropython.org>
Support for raw str/bytes already exists, and extending that to raw
f-strings is easy. It also reduces code size because it eliminates an
error message.
Signed-off-by: Damien George <damien@micropython.org>