summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
8 dayspy/formatfloat: Improve accuracy of float formatting code.Yoctopuce dev
Following discussions in PR #16666, this commit updates the float formatting code to improve the `repr` reversibility, i.e. the percentage of valid floating point numbers that do parse back to the same number when formatted by `repr` (in CPython it's 100%). This new code offers a choice of 3 float conversion methods, depending on the desired tradeoff between code size and conversion precision: - BASIC method is the smallest code footprint - APPROX method uses an iterative method to approximate the exact representation, which is a bit slower but but does not have a big impact on code size. It provides `repr` reversibility on >99.8% of the cases in double precision, and on >98.5% in single precision (except with REPR_C, where reversibility is 100% as the last two bits are not taken into account). - EXACT method uses higher-precision floats during conversion, which provides perfect results but has a higher impact on code size. It is faster than APPROX method, and faster than the CPython equivalent implementation. It is however not available on all compilers when using FLOAT_IMPL_DOUBLE. Here is the table comparing the impact of the three conversion methods on code footprint on PYBV10 (using single-precision floats) and reversibility rate for both single-precision and double-precision floats. The table includes current situation as a baseline for the comparison: PYBV10 REPR_C FLOAT DOUBLE current = 364688 12.9% 27.6% 37.9% basic = 364812 85.6% 60.5% 85.7% approx = 365080 100.0% 98.5% 99.8% exact = 366408 100.0% 100.0% 100.0% Signed-off-by: Yoctopuce dev <dev@yoctopuce.com>
8 dayspy/parsenum: Refactor float parsing code.Yoctopuce dev
This commit extracts from the current float parsing code two functions which could be reused elsewhere in MicroPython. The code used to multiply a float x by a power of 10 is also simplified by applying the binary exponent separately from the power of 5. This avoids the risk of overflow in the intermediate stage, before multiplying by x. Signed-off-by: Yoctopuce dev <dev@yoctopuce.com>
9 dayswebassembly/proxy_js: Reuse JsProxy ref if object matches.Damien George
This reduces memory use by reusing objects, and improves identity/equality relationships of JavaScript objects on the Python side. In 77bd8fe5b80b0e7e02cdb6b4272c401ae3dca638 PyProxy's were reused when the same Python object was proxied across to JavaScript. This commit does the same thing but for JsProxy's going from JS to Python. If an existing JsProxy reference exists for the JS object about to be proxied across, then it's reused. This helps reduce the number of alive objects (memory use), and, more importantly, improves equality relationships of JavaScript objects on the Python side. Eg we now get, on the Python side: import js print(js.Object == js.Object) that prints True. Previously it was False. Note that this change does not make identity work with `is`, for example `js.Object is js.Object` is actually False. With more work that could be made True but for now we leave that as-is. The behaviour with this commit matches Pyodide semantics. Signed-off-by: Damien George <damien@micropython.org>
9 dayswebassembly/objjsproxy: Implement equality for JsProxy objects.Damien George
Signed-off-by: Damien George <damien@micropython.org>
9 dayspy/objboundmeth: Add option to use mp_is_equal instead of == comparison.Damien George
This option is needed for ports such as webassembly where objects are proxied and can be identical without being the same C pointer. Signed-off-by: Damien George <damien@micropython.org>
9 daystests/run-multitests.py: Escape encoding errors instead of crashing.Angus Gratton
It's possible for a test to output non-ASCII characters (for example, due to a hard fault or serial noise or memory corruption). Rather than crashing the test runner, backslash escape those characters and treat them as program output. Refactors the string encoding step to a single helper to avoid copy-paste. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
9 daystests/multi_bluetooth: Extend the deep sleep test timeout.Angus Gratton
As per comment, if a boot.py is present that connects to Wi-Fi then waking can take a little longer. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
9 daystests/run-natmodtests.py: Automatically skip tests that are too large.Damien George
This follows a similar change made for `run-tests.py` in commit 229104558fb7f9d283b7302bc3720bc35c5c49cf. The change here uses the same logic to detect if a natmod test is too big for the target (eg overflows (I)RAM loading the native .mpy), by printing "START TEST" at the start of the test. Typical output is now something like this: ... pass extmod/random_basic.py pass extmod/random_extra_float.py pass extmod/random_extra.py SKIP extmod/random_seed_default.py LRGE extmod/re1.py SKIP extmod/re_debug.py pass extmod/re_error.py pass extmod/re_group.py pass extmod/re_groups.py ... and the tests that are too large are reported at the end, and written to the `_result.json` file. Signed-off-by: Damien George <damien@micropython.org>
9 daysexamples/bluetooth/ble_advertising.py: Fix decoding UUIDs.Damien George
The UUID32 case was incorrect: first, the "<d" should have been "<I", and second, the UUID constructor treats integer arguments as UUID16. So this UUID32 case needs to pass in the actual data bytes. And then it's simpler to just make all cases pass in the data bytes. Signed-off-by: Damien George <damien@micropython.org>
9 daysdocs/library/bluetooth: Document all allowed args to UUID constructor.Damien George
Signed-off-by: Damien George <damien@micropython.org>
9 dayszephyr/mpconfigport: Use MICROPY_CONFIG_ROM_LEVEL_BASIC_FEATURES.Damien George
This commit adjusts the configuration of the standard zephyr build to use MICROPY_CONFIG_ROM_LEVEL_BASIC_FEATURES. That's a lot cleaner than explicitly enabling/disabling options, and allows boards to more easily fine-tune the settings, eg select a different feature level. Features that are now enabled are: - async/await keyword support - `filter`, `property` and `reversed` builtins - `range` attributes - `str.count()` method - `array` module with `array.array` object - `collections` module with `collections.namedtuple` object - `struct` module with everything - `id = const()` and constant folding in the compiler Bulding qemu_cortex_m3, the code size was originally: Memory region Used Size Region Size %age Used FLASH: 193864 B 256 KB 73.95% RAM: 61992 B 64 KB 94.59% and with this commit it is now: Memory region Used Size Region Size %age Used FLASH: 200698 B 256 KB 76.56% RAM: 61992 B 64 KB 94.59% That's a mild increase of +6834 bytes flash usage for a good selection of new features. Signed-off-by: Damien George <damien@micropython.org>
9 dayszephyr/mpconfigport_minimal: Use MICROPY_CONFIG_ROM_LEVEL_MINIMUM.Damien George
This commit adjusts the configuration of the minimal zephyr build to use MICROPY_CONFIG_ROM_LEVEL_MINIMUM. That's a lot cleaner than explicitly enabling/disabling options. Prior to this change the minimal build for qemu_cortex_m3 had size: Memory region Used Size Region Size %age Used FLASH: 114436 B 256 KB 43.65% RAM: 26320 B 64 KB 40.16% and had the following test results (running using the CI settings, ie `-d basics float --exclude inf_nan_arith`): 352 tests performed (7092 individual testcases) 352 tests passed 254 tests skipped: ... With the changes here the qemu_cortex_m3 size is now: Memory region Used Size Region Size %age Used FLASH: 99428 B 256 KB 37.93% RAM: 26312 B 64 KB 40.15% That's a good decrease of about 15k firmware size. And the test suite still passes with: 342 tests performed (6776 individual testcases) 341 tests passed 265 tests skipped: ... Signed-off-by: Damien George <damien@micropython.org>
9 daysextmod/modtls_mbedtls: Do gc_collect and retry ssl_init on any error.Damien George
Contrary to the docs, mbedtls can return more than just MBEDTLS_ERR_SSL_ALLOC_FAILED when `mbedtls_ssl_setup()` fails. At least MBEDTLS_ERR_MD_ALLOC_FAILED was also seen on ESP32_GENERIC, but there could possibly be other error codes. To cover all these codes, just check if `ret` is non-0, and in that case do a `gc_collect()` and retry the init. Signed-off-by: Damien George <damien@micropython.org>
10 dayspy/mphal: Add stddef.h header for size_t.Yanfeng Liu
This includes "stddef.h" for `size_t` to resolve NuttX integration build issues. Signed-off-by: Yanfeng Liu <yfliu2008@qq.com>
10 daysesp32: Fix first line ESP32-C2 serial output after reset or deepsleep.Angus Gratton
ESP32-C2 ROM prints at 74880bps (same as ESP8266), so need a newline before first MicroPython output to avoid it being appended on end of a line of noise. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
10 daysesp32: Add "Free RAM" optimisation config flags.Angus Gratton
This is necessary for ESP32-C2 Wi-Fi & BT to work reliably (and for TLS to work at all). On IDF 5.4.2 the free static RAM goes from 60KB to 100KB, and there will also be a reduction in lwIP & Wi-Fi memory use at runtime. The performance trade-off seems low for most use cases, although it will probably be significant for certain combinations of load (i.e. heavy TCP/IP, heavy BT throughput, and some peripheral driver functions). Added as a set of config flags because this is potentially useful on other SoCs where the goal is to maximise RAM available for MicroPython. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
10 daysesp32: Add support for ESP32-C2 (aka ESP8684).TianShuang Ke
Includes: esp32/esp32c2: Adapt to target chip ESP32C2. esp32/esp32c2: Fix heap size is too small to enable Bluetooth. Signed-off-by: TianShuangKe <qinyun575@gmail.com> Signed-off-by: Angus Gratton <angus@redyak.com.au>
11 daystests/run-internalbench.py: Allow running internalbench on hardware.Anson Mansfield
Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
11 daystests/internal_bench/var: Benchmark descriptor access.Anson Mansfield
Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
11 daystests/internal_bench/class_create: Benchmark class creation.Anson Mansfield
Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
11 daysdocs: Document PEP487 __set_name__ implementation.Anson Mansfield
Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
11 dayspy/objtype: Add support for PEP487 __set_name__.Anson Mansfield
This commit adds support for the `__set_name__` data model method specified by PEP487 - Simpler customisation of class creation. This includes support for methods that mutate the owner class, and avoids the naive modify-while-iterating hazard possible in a naive implementation like micropython/micropython#15503. Note that based on the benchmarks in micropython/micropython#16825, this is also as fast or faster than the naive implementation, thanks to clever data layout in `setname_list_t`, and the way this allows the capture step to run during an existing loop through the class dict. Other rejected approaches for dealing with the hazard include: - python/cpython#72983 During the implementation of this feature for MicroPython, it was discovered that some versions of CPython also have this naive hazard. CPython resolved this bug in BPO-28797 and now makes a complete flat copy of the class's dict to iterate. This design decision doesn't make much sense for a microcontroller though, even if it's perfectly reasonable in the desktop world where memcpy might actually be cheaper than a hard-to-branch-predict conditional; and it's also motivated in their case by error-tracing considerations. - micropython/micropython#16816 This is an equivalent implementation to CPython's approach that places this copy directly on the stack; however it is both slower and has larger code size than the approach taken here. - micropython/micropython#15503 The simplest implementation is to just not worry about it and let the user face the consequences if they mutate the owner class. That's not a very friendly behavior, though, and it's not actually much more performant than this implementation on either time or code size. - micropython/micropython#17693 Another alternative is to do the same as #15503 but leverage MicroPython's existing `is_fixed` field in its dict type to convert attempted mutations of the owner dict into `AttributeError`s. This is safer than just leaving the open hazard, but there's still important use-cases for owner-mutating descriptors, and the performance gain is small enough that it isn't worth missing support for those cases. - combined micropython/micropython#17693 with this Another version of this feature used a new feature define, `MICROPY_PY_METACLASSES_LITE`, to control whether this algorithm or the naive version is used. This was rejected in favor of simplicity, based on the very limited performance margin the naive version has (which in some cases even goes _against_ it). Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
11 daystests/basics: Add tests for PEP487 __set_name__.Anson Mansfield
Including the stochastic tests needed to guarantee sensitivity to the potential iterate-while-modifying hazard a naive implementation might have. Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
11 dayspy/objint_longlong: Fix longlong interoperability with floats.Yoctopuce dev
Current longlong implementation does not allow a float as RHS of mathematic operators, as it lacks the delegation code present in mpz. Signed-off-by: Yoctopuce dev <dev@yoctopuce.com>
11 dayspy/objint_longlong: Fix overflow check in mp_obj_int_get_checked.Yoctopuce dev
This is to fix an outstanding TODO. The test cases is using a range as this will exist in all builds, but `mp_obj_get_int` is used in many different parts of code where an overflow is more likely to occur. Signed-off-by: Yoctopuce dev <dev@yoctopuce.com>
11 dayspy/objint_mpz: Fix pow3 where third argument is zero.Jeff Epler
This finding is based on fuzzing MicroPython. I manually minimized the test case it provided. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25rp2/modmachine: Do not use deprecated XOSC_MHZ and XOSC_KHZ.Christian Lang
XOSC_MHZ and XOSC_KHZ may not be defined if we use a custom XIN clock by defining PLL_SYS_REFDIV etc. calculated by vcocalc.py. Signed-off-by: Christian Lang <lang.chr86@gmail.com>
2025-07-25py/mpprint: Fix printing pointers with upper bit set.Jeff Epler
On a build like nanbox, `mp_uint_t` is wider than `u/intptr_t`. Using a signed type for fetching pointer values resulted in erroneous results: like `<function f at 0xfffffffff7a60bc0>` instead of `<function f at 0xf7a60bc0>`. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25stm32: Add casts when printing small integers.Jeff Epler
All these arguments are of type `mp_{u,}int_t`, but the actual value is always a small integer. Cast it so that it can format with the `%d/%u` formatter. Before, the compiler plugin produced an error in the PYBD_SF6 build, which is a nanboxing build with 64-bit ints. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25py/objcell: Fix printing of cell ID/pointer.Jeff Epler
On the nanbox build, `o->obj` is a 64-bit type but `%p` formats a 32-bit type, leading to undefined behavior. Print the cell's ID as a hex integer instead. This location was found using an experimental gcc plugin for `mp_printf` error checking. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25shared/netutils: Cast the ticks value before printing.Jeff Epler
Before, the compiler plugin produced an error in the PYBD_SF6 build, which is a nanboxing build with 64-bit ints. I made the decision here to cast the value even though some significant bits might be lost after 49.7 days. However, the format used is "% 8d", which produces a consistent width output for small ticks values (up to about 1.1 days). I judged that it was more valuable to preserve the fixed width display than to accurately represent long time periods. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25extmod/modlwip: Print timeout with correct format string.Jeff Epler
As timeout is of type `mp_uint_t`, it must be printed with UINT_FMT. Before, the compiler plugin produced an error in the PYBD_SF6 build, which is a nanboxing build with 64-bit ints. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25examples/usercmodule: Cast arguments for printf.Jeff Epler
These locations were found using an experimental gcc plugin for `mp_printf` error checking. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25unix/coverage: Remove unused printf arguments.Jeff Epler
Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25unix/coverage: Provide argmuents of expected integer types.Jeff Epler
Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25unix/coverage: Cast values to int for format printing.Jeff Epler
During the coverage test, all the values encountered are within the range of `%d`. These locations were found using an experimental gcc plugin for `mp_printf` error checking. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25unix/coverage: Cast values to fit %x formatting code.Jeff Epler
This fixes the following diagnostic produced by the plugin: error: argument 3: Format ‘%x’ requires a ‘int’ or ‘unsigned int’ (32 bits), not ‘long unsigned int’ [size 64] [-Werror=format=] Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25unix/coverage: Cast type names to qstr explicitly.Jeff Epler
Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25unix/coverage: Avoid type checking an invalid string.Jeff Epler
We still want this not to crash a runtime but the new static checker wouldn't like it. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25py: Fix mp_printf integer size mismatches.Jeff Epler
The type of the argument must match the format string. Add casts to ensure that they do. It's possible that casting from `size_t` to `unsigned` loses the correct values by masking off upper bits, but it seems likely that the quantities involved in practice are small enough that the `%u` formatter (32 bits on most platforms, 16 on pic16bit) will in fact hold the correct value. The alternative, casting to a wider type, adds code size. These locations were found using an experimental gcc plugin for `mp_printf` error checking, cross-building for x64 windows on Linux. In one case there was already a cast, but it was written incorrectly and did not have the intended effect. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25py: Cast type names to qstr explicitly.Jeff Epler
The name field of type objects is of type `uint16_t` for efficiency, but when the type is passed to `mp_printf` it must be cast explicitly to type `qstr`. These locations were found using an experimental gcc plugin for `mp_printf` error checking, cross-building for x64 windows on Linux. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25py/mpconfig,ports: Define new HEX_FMT formatting macro.Jeff Epler
Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-25ports: Eliminate define of {U,}INT_FMT where redundant.Jeff Epler
The default definition in `py/mpconfig.h` for 32-bit architectures is `%u/%d`, so these can be removed. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-07-24tests/micropython: Rename viper boundary tests that depend on big int.Angus Gratton
These tests all depend on generating arbitrarily long (>64-bit) integers. It would be possible to have these tests work in this case I think, as the results are always masked to shorter values. But quite fiddly. So just rename them so they are automatically skipped if the target doesn't have big int support. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
2025-07-24py/objint_longlong: Fix left shift of negative values.Angus Gratton
Previous comment was wrong, left shifting a negative value is UB in C. Use the same approach as small int shifts (from runtime.c). Signed-off-by: Angus Gratton <angus@redyak.com.au>
2025-07-24py/obj: Add new type flag to indicate subscr accepts slice-on-stack.Damien George
The recently merged 5e9189d6d1c00c92694888bf9c74276779c40716 now allows temporary slices to be allocated on the C stack, which is much better than allocating them on the GC heap. Unfortunately there are cases where the C-allocated slice can escape and be retained as an object, which leads to crashes (because that object points to the C stack which now has other values on it). The fix here is to add a new `MP_TYPE_FLAG_SUBSCR_ALLOWS_STACK_SLICE`. Native types should set this flag if their subscr method is guaranteed not to hold on to a reference of the slice object. Fixes issue #17733 (see also #17723). Signed-off-by: Damien George <damien@micropython.org>
2025-07-24webassembly/objjsproxy: Fix binding of self to JavaScript methods.Damien George
Fixes a bug in the binding of self/this to JavaScript methods. The new semantics match Pyodide's behaviour, at least for the included tests. Signed-off-by: Damien George <damien@micropython.org>
2025-07-24webassembly/proxy_c: Provide constants for fixed JsProxy refs.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2025-07-24tools/ci.sh: Test building all natmod examples with all ARM-M archs.Damien George
And run both armv6m and armv7m under qemu. Signed-off-by: Damien George <damien@micropython.org>
2025-07-24qemu/Makefile: Allow passing flags to test_natmod via RUN_TESTS_EXTRA.Damien George
Signed-off-by: Damien George <damien@micropython.org>