Make tests run in an isolated environment (i.e. `import io` would
otherwise get the `tests/io` directory).
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
Make tests run in an isolated environment (i.e. `import io` would
otherwise get the `tests/io` directory).
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
Prior to this commit, importing a module that exists but has a syntax error
or some other problem that happens at import time would result in a
potentially-incomplete module object getting added to sys.modules.
Subsequent imports would use that object, resulting in confusing error
messages that hide the root cause of the problem.
This commit fixes that issue by removing the failed module from sys.modules
using the new NLR callback mechanism.
Note that it is still important to add the module to sys.modules while the
import is happening so that we can support circular imports just like
CPython does.
Fixes issue #967.
Signed-off-by: David Grayson <davidegrayson@gmail.com>
When foo.bar is imported, bar is added as an attribute to foo. Previously
this happened on every import, but should only happen on first import.
This verifies the behavior for relative imports and overriding.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This verifies the behavior:
- Exact matches of built-ins bypass filesystem.
- u-prefix modules can be overridden from the filesystem.
- Builtin import can be forced using either u-prefix or sys.path=[].
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This demonstrates how to add a sub-package in a user c module, as well
as how to define the necessary qstrs and enable the feature in the build.
This is used by the unix coverage build to test this feature.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This generalises and simplifies the code and follows CPython behaviour.
See similar change for floats in a07fc5b640.
Signed-off-by: Damien George <damien@micropython.org>
This is possible now that MP_UNARY_OP_INT_MAYBE exists.
As a consequence mp_obj_get_int now also supports user types, which was
previously possible with MP_UNARY_OP_INT but no tests existed for it.
Signed-off-by: Damien George <damien@micropython.org>
To be consistent with MP_UNARY_OP_INT_FLOAT and MP_UNARY_OP_INT_COMPLEX,
and allow int() to first check if a type supports __int__ before trying
other things (as per CPython).
Signed-off-by: Damien George <damien@micropython.org>
MicroPython does not support these special methods, and they may get in the
way of other tests (eg indexing with __int__).
Signed-off-by: Damien George <damien@micropython.org>
The code that handles inplace-operator to normal-binary-operator fallback
is moved in this commit from py/objtype.c to py/runtime.c, making it apply
to all types, not just user classes.
Signed-off-by: Damien George <damien@micropython.org>
So that user types can implement reverse operators and have them work with
str on the left-hand-side, eg `"a" + UserType()`.
Signed-off-by: Damien George <damien@micropython.org>
This adds a unary_op implementation for the dict_view type that makes
the implementation of `hash()` for these types compatible with CPython.
Signed-off-by: David Lechner <david@pybricks.com>
As per https://bugs.python.org/issue408326, the slice object should not be
hashable. Since MicroPython has an implicit fallback when the unary_op
slot is empty, we need to fill this slot.
Signed-off-by: David Lechner <david@pybricks.com>
Previously when using --via-mpy, the file was compiled to tests/<tmp>.mpy
and then run using `micropython -m <tmp>` in the current cwd
(usually tests/). This meant that an import in the test would be resolved
relative to tests/.
This is different to regular (non-via-mpy) tests, where we run (for
example) `micropython basics/test.py` which means that an import would be
resolved relative to basics/.
Now --via-mpy matches the .py behavior. This is important because:
a) It makes it so import tests do the right thing.
b) There are directory names in tests/ that match built-in module names.
Furthermore, it always ensures the cwd (for both micropython and cpython)
is the test directory (e.g. basics/) rather than being left unset. This
also makes it clearer inside the test that e.g. file access is relative to
the Python file.
Updated tests with file paths to match.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
When a tuple is the condition of an if statement, it's only possible to
optimise that tuple away when it is a constant tuple (ie all its elements
are constants), because if it's not constant then the elements must be
evaluated in case they have side effects (even though the resulting tuple
will always be "true").
The code before this change handled the empty tuple OK (because it doesn't
need to be evaluated), but it discarded non-empty tuples without evaluating
them, which is incorrect behaviour (as show by the updated test).
This optimisation is anyway rarely applied because it's not common Python
coding practice to write things like `if (): ...` and `if (1, 2): ...`, so
removing this optimisation completely won't affect much code, if any.
Furthermore, when MICROPY_COMP_CONST_TUPLE is enabled, constant tuples are
already optimised by the parser, so expression with constant tuples like
`if (): ...` and `if (1, 2): ...` will continue to be optimised properly
(and so when this option is enabled the code that's deleted in this commit
is actually unreachable when the if condition is a constant tuple).
Signed-off-by: Damien George <damien@micropython.org>
ESP-NOW is a proprietary wireless communication protocol which supports
connectionless communication between ESP32 and ESP8266 devices, using
vendor specific WiFi frames. This commit adds support for this protocol
through a new `espnow` module.
This commit builds on original work done by @nickzoic, @shawwwn and with
contributions from @zoland. Features include:
- Use of (extended) ring buffers in py/ringbuf.[ch] for robust IO.
- Signal strength (RSSI) monitoring.
- Core support in `_espnow` C module, extended by `espnow.py` module.
- Asyncio support via `aioespnow.py` module (separate to this commit).
- Docs provided at `docs/library/espnow.rst`.
Methods available in espnow.ESPNow class are:
- active(True/False)
- config(): set rx buffer size, read timeout and tx rate
- recv()/irecv()/recvinto() to read incoming messages from peers
- send() to send messages to peer devices
- any() to test if a message is ready to read
- irq() to set callback for received messages
- stats() returns transfer stats:
(tx_pkts, tx_pkt_responses, tx_failures, rx_pkts, lost_rx_pkts)
- add_peer(mac, ...) registers a peer before sending messages
- get_peer(mac) returns peer info: (mac, lmk, channel, ifidx, encrypt)
- mod_peer(mac, ...) changes peer info parameters
- get_peers() returns all peer info tuples
- peers_table supports RSSI signal monitoring for received messages:
{peer1: [rssi, time_ms], peer2: [rssi, time_ms], ...}
ESP8266 is a pared down version of the ESP32 ESPNow support due to code
size restrictions and differences in the low-level API. See docs for
details.
Also included is a test suite in tests/multi_espnow. This tests basic
espnow data transfer, multiple transfers, various message sizes, encrypted
messages (pmk and lmk), and asyncio support.
Initial work is from https://github.com/micropython/micropython/pull/4115.
Initial import of code is from:
https://github.com/nickzoic/micropython/tree/espnow-4115.
Changes in this commit:
- Change MICROPY_HW_BOARD_NAME definition to match the product name.
- Rename board folder's name to match the product name style.
- Change related files like Makefile, document descriptions, test cases, CI
and tools.
Signed-off-by: Takeo Takahashi <takeo.takahashi.xv@renesas.com>
btstack only supports central-initiated, so this allows us to have a test
that works on both (ble_mtu.py), and then another one for just the NimBLE
supported behavior (ble_mtu_peripheral.py).
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
On unix, time.sleep is implemented as select(timeout=<time>) which means
that it does not run the poll hook during sleeping.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
Following other vfs_fat tests, so the test works on ports like stm32 that
only support 512-byte block size.
Signed-off-by: Damien George <damien@micropython.org>
If a multitest calls `multitest.output_metric(...)` then that output will
be collected separately, not considered as part of the test verification
output, and instead be printed at the end. This is useful for tests that
want to output performance/timing metrics that may change from one run to
the next.
Signed-off-by: Damien George <damien@micropython.org>
When iterating over os.ilistdir(), the special directories '.' and '..'
are filtered from the results. But the code inadvertently also filtered
any file/directory which happened to match '..*'. This change fixes the
filter.
Fixes issue #11032.
Signed-off-by: Jeremy Rand <jeremy@rand-family.com>
When := is used in a comprehension the target variable is bound to the
parent scope, so it's either a global or a nonlocal. Prior to this commit
that was handled by simply using the parent scope's id_info for the
target variable. That's completely wrong because it uses the slot number
for the parent's Python stack to store the variable, rather than the slot
number for the comprehension. This will in most cases lead to incorrect
behaviour or memory faults.
This commit fixes the scoping of the target variable by explicitly
declaring it a global or nonlocal, depending on whether the parent is the
global scope or not. Then the id_info of the comprehension can be used to
access the target variable. This fixes a lot of cases of using := in a
comprehension.
Code size change for this commit:
bare-arm: +0 +0.000%
minimal x86: +0 +0.000%
unix x64: +152 +0.019% standard
stm32: +96 +0.024% PYBV10
cc3200: +96 +0.052%
esp8266: +196 +0.028% GENERIC
esp32: +156 +0.010% GENERIC[incl +8(data)]
mimxrt: +96 +0.027% TEENSY40
renesas-ra: +88 +0.014% RA6M2_EK
nrf: +88 +0.048% pca10040
rp2: +104 +0.020% PICO
samd: +88 +0.033% ADAFRUIT_ITSYBITSY_M4_EXPRESS
Fixes issue #10895.
Signed-off-by: Damien George <damien@micropython.org>
The device-under-test should use `multitest.expect_reboot()` to indicate
that it will reboot.
Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Prior to this fix, pow(1.5, inf) and pow(0.5, -inf) (among other things)
would incorrectly raise a ValueError, because the result is inf with the
first argument being finite. This commit fixes this by allowing the result
to be infinite if the first or second (or both) argument is infinite.
This fix doesn't affect the other three math functions that have two
arguments:
- atan2 never returns inf, so always fails isinf(ans)
- copysign returns inf only if the first argument x is inf, so will never
reach the isinf(y) check
- fmod never returns inf, so always fails isinf(ans)
Signed-off-by: Damien George <damien@micropython.org>
So it can run on targets with low memory, eg esp8266.
Also enable the viper_4args() sub-test, which is now supported.
Signed-off-by: Damien George <damien@micropython.org>
This is important for literal tuples, e.g.
f"{a,b,}, {c}" --> "{}".format((a,b), (c),)
which would otherwise result in either a syntax error or the wrong result.
Fixes issue #9635.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
32-bit platforms only support a slice offset start of 24 bit max due to the
limited size of the mp_obj_array_t.free member. Similarly on 64-bit
platforms the limit is 56 bits.
This commit adds an OverflowError if the user attempts to slice a
memoryview beyond this limit.
Signed-off-by: Damien George <damien@micropython.org>
In @micropython.native code the types of variables and expressions are
always Python objects, so they can be initialised as such. This prevents
problems with compiling optimised code like while-loops where a local may
be referenced before it is assigned to.
Signed-off-by: Damien George <damien@micropython.org>
During the initial handshake or subsequent renegotiation, the protocol
might need to read in order to write (or conversely to write in order
to read). It might be blocked from doing so by the state of the
underlying socket (i.e. there is no data to read, or there is no space
to write).
The library indicates this condition by returning one of the errors
`MBEDTLS_ERR_SSL_WANT_READ` or `MBEDTLS_ERR_SSL_WANT_WRITE`. When that
happens, we need to enforce that the next poll operation only considers
the direction that the library indicated.
In addition, mbedtls does its own read buffering that we need to take
into account while polling, and we need to save the last error between
read()/write() and ioctl().