summaryrefslogtreecommitdiffstatshomepage
path: root/py
Commit message (Collapse)AuthorAge
* py/objmodule: Workaround for MSVC with no module delegation.Jim Mussared2023-06-08
| | | | | | | | | | When compiling mpy-cross, there is no `sys` module, and so there will be no entries in the `mp_builtin_module_delegation_table`. MSVC doesn't like this, so instead pretend as if the feature isn't enabled at all. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* py/objmodule: Add a table of built-in modules with delegation.Jim Mussared2023-06-08
| | | | | | | | | | | | | | | | | This replaces the previous QSTR_null entry in the globals dict which could leak out to Python (e.g. via iteration of mod.__dict__) and could lead to crashes. It results in smaller code size at the expense of turning a lookup into a loop, but the list it is looping over likely only contains one or two elements. To allow a module to register its custom attr function it can use the new `MP_REGISTER_MODULE_DELEGATION` macro. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* all: Use MP_REGISTER_EXTENSIBLE_MODULE for overrideable built-ins.Jim Mussared2023-06-08
| | | | Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* py/makemoduledefs.py: Add a way to register extensible built-in modules.Jim Mussared2023-06-08
| | | | Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* all: Rename *umodule*.c to remove the "u" prefix.Jim Mussared2023-06-08
| | | | | | | | | | | Updates any includes, and references from Makefiles/CMake. This essentially reverts what was done long ago in commit 136b5cbd7669e8318f8455fc2706da97a5b7994c This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* all: Rename *umodule*.h to remove the "u" prefix.Jim Mussared2023-06-08
| | | | | | | | This work was funded through GitHub Sponsors. Also updates #includes. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* all: Rename UMODULE to MODULE in preprocessor/Makefile vars.Jim Mussared2023-06-08
| | | | | | This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* all: Rename mod_umodule*, ^umodule* to remove the "u" prefix.Jim Mussared2023-06-08
| | | | | | This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* all: Rename mp_umodule*, mp_module_umodule* to remove the "u" prefix.Jim Mussared2023-06-08
| | | | | | This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* py/builtinimport: Remove weak links.Jim Mussared2023-06-08
| | | | | | | | | | | | | | In order to keep "import umodule" working, the existing mechanism is replaced with a simple fallback to drop the "u". This makes importing of built-ins no longer touch the filesystem, which makes a typical built-in import take ~0.15ms rather than 3-5ms. (Weak links were added in c14a81662c1df812c0c6b4299f97966302f16477) This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* all: Rename MP_QSTR_umodule to MP_QSTR_module everywhere.Jim Mussared2023-06-08
| | | | | | | | | This renames the builtin-modules, such that help('modules') and printing the module object will show "module" rather than "umodule". This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* py/builtinimport: Remove partially-loaded modules from sys.modules.David Grayson2023-06-05
| | | | | | | | | | | | | | | | | | | 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>
* py: Use nlr jump callbacks to optimise compile/execute functions.Damien George2023-06-02
| | | | | | | | | | The changed functions now use less stack, and don't have any issues with local variables needing to be declared volatile. Testing on a PYBv1.0, imports (of .py, .mpy and frozen code) now use 64 less bytes of C stack per import depth. Signed-off-by: Damien George <damien@micropython.org>
* py/nlr: Implement jump callbacks.Damien George2023-06-02
| | | | | | | | | | | | | | NLR buffers are usually quite large (use lots of C stack) and expensive to push and pop. Some of the time they are only needed to perform clean up if an exception happens, and then they re-raise the exception. This commit allows optimizing that scenario by introducing a linked-list of NLR callbacks that are called automatically when an exception is raised. They are essentially a light-weight NLR handler that can implement a "finally" block, i.e. clean-up when an exception is raised, or (by passing `true` to nlr_pop_jump_callback) when execution leaves the scope. Signed-off-by: Damien George <damien@micropython.org>
* py/nlr: Remove commented-out debugging code.Damien George2023-06-02
| | | | | | Also remove the unnecessary include of mpstate.h. Signed-off-by: Damien George <damien@micropython.org>
* py/nlrsetjmp: Use MP_NLR_JUMP_HEAD macro to simplify code.Damien George2023-06-02
| | | | Signed-off-by: Damien George <damien@micropython.org>
* py/objmodule: Don't use sys.modules to track a builtin __init__.Jim Mussared2023-06-01
| | | | | | | | | | | | | This can lead to duplicate initialisations if a module can be imported via multiple names, so the module must track this itself anyway. This reduces code size (diff is -40 bytes), and avoids special treatment of builtin-modules-with-init with respect to sys.modules. No other builtin modules get put into sys.modules. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* py/builtinimport: Allow builtin modules to be packages.Jim Mussared2023-06-01
| | | | | | | | | | | | | | | | | | | | To use this: - Create a built-in module, and add the module object as a member of the parent module's globals dict. - The submodule can set its `__name__` to either `QSTR_foo_dot_bar` or `QSTR_bar`. The former requires using qstrdefs(port).h to make the qstr. Because `bar` is a member of `foo`'s globals, it is possible to write `import foo` and then immediately use `foo.bar` without importing it explicitly. This means that if `bar` has an `__init__`, it will not be called in this situation, and for that reason, sub-modules should not have `__init__` methods. If this is required, then all initalisation for sub-modules should be done by the top-level module's (i.e. `foo`'s) `__init__` method. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* py/builtinimport: Optimise sub-package loading.Jim Mussared2023-06-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This makes it so that sub-packages are resolved relative to their parent's `__path__`, rather than re-resolving each parent's filesystem path. The previous behavior was that `import foo.bar` would first re-search `sys.path` for `foo`, then use the resulting path to find `bar`. For already-loaded and u-prefixed modules, because we no longer need to build the path from level to level, we no longer unnecessarily search the filesystem. This should improve startup time. Explicitly makes the resolving process clear: - Loaded modules are returned immediately without touching the filesystem. - Exact-match of builtins are also returned immediately. - Then the filesystem search happens. - If that fails, then the weak-link handling is applied. This maintains the existing behavior: if a user writes `import time` they will get time.py if it exits, otherwise the built-in utime. Whereas `import utime` will always return the built-in. This also fixes a regression from a7fa18c203a241f670f12ab507aa8b349fcd45a1 where we search the filesystem for built-ins. It is now only possible to override u-prefixed builtins. This will remove a lot of filesystem stats at startup, as micropython-specific modules (e.g. `pyb`) will no longer attempt to look at the filesystem. Added several improvements to the comments and some minor renaming and refactoring to make it clearer how the import mechanism works. Overall code size diff is +56 bytes on STM32. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* py/builtinimport: Handle empty sys.path correctly.Jim Mussared2023-06-01
| | | | | | | | | | | | | | | | | | | | | | | | | If sys.path is enabled, but empty, this will now no longer search the filesystem. Previously an empty sys.path was equivalent to having `sys.path=[""]`. This is a breaking change, but this behavior now matches CPython. This also provides an alternative mechanism to the u-prefix to force an import of a builtin module: ``` import sys _path = sys.path[:] sys.path.clear() import foo # Forces the built-in foo. sys.path.extend(_path) del _path ``` Code size diff is -32 bytes on PYBV11. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* py/objint: Allow int() to parse anything with the buffer protocol.Damien George2023-06-01
| | | | | | | | This generalises and simplifies the code and follows CPython behaviour. See similar change for floats in a07fc5b6403b9a8bf7e7cb64f857272e5346d7e2. Signed-off-by: Damien George <damien@micropython.org>
* py/obj: Accept user types in mp_obj_get_int_maybe.Damien George2023-06-01
| | | | | | | | | 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>
* py: Change MP_UNARY_OP_INT to MP_UNARY_OP_INT_MAYBE.Damien George2023-06-01
| | | | | | | | 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>
* py/runtime: If inplace binop fails then try corresponding normal binop.Damien George2023-05-19
| | | | | | | | 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>
* py/objstr: Return unsupported binop instead of raising TypeError.Damien George2023-05-19
| | | | | | | 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>
* py/objarray: Disallow memoryview addition.Damien George2023-05-19
| | | | | | | Following CPython. This is important for subsequent commits to work correctly. Signed-off-by: Damien George <damien@micropython.org>
* py/objdict: Fix __hash__ for dict_view types.David Lechner2023-05-19
| | | | | | | 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>
* py/objslice: Ensure slice is not hashable.David Lechner2023-05-19
| | | | | | | | 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>
* py/obj: Remove mp_generic_unary_op().David Lechner2023-05-19
| | | | | | | | | Since converting to variable sized slots in mp_obj_type_t, we can now reduce the code size a bit by removing mp_generic_unary_op() and the corresponding slots where it is used. Instead we just implement the generic `__hash__` operation in the runtime. Signed-off-by: David Lechner <david@pybricks.com>
* py/gc: Make improvements to MICROPY_GC_HOOK_LOOP.David Lechner2023-05-09
| | | | | | | | | | | Changes in this commit: - Add MICROPY_GC_HOOK_LOOP to gc_info() and gc_alloc(). Both of these can be long running (many milliseconds) which is too long to be blocking in some applications. - Pass loop variable to MICROPY_GC_HOOK_LOOP(i) macro so that implementers can use it, e.g. to improve performance by only calling a function every X number of iterations. - Drop outer call to MICROPY_GC_HOOK_LOOP in gc_mark_subtree().
* py/stackctrl: Add gcc pragmas to ignore dangling-pointer warning.Damien George2023-05-04
| | | | | | This warning became apparent in gcc 13. Signed-off-by: Damien George <damien@micropython.org>
* py/compile: Remove over-eager optimisation of tuples as if condition.Damien George2023-05-03
| | | | | | | | | | | | | | | | | | | | | | | | 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>
* py/parse: Fix build when COMP_CONST_FOLDING=0 and COMP_MODULE_CONST=1.Damien George2023-05-03
| | | | Signed-off-by: Damien George <damien@micropython.org>
* py/ringbuf: Implement put_bytes/get_bytes functions.glenn202023-05-01
|
* all: Fix spelling mistakes based on codespell check.Damien George2023-04-27
| | | | Signed-off-by: Damien George <damien@micropython.org>
* extmod/modutime: Provide a generic time module.Damien George2023-04-27
| | | | | | | | | | | | | | | Based on extmod/utime_mphal.c, with: - a globals dict added - time.localtime wrapper added - time.time wrapper added - time.time_ns function added New configuration options are added for this module: - MICROPY_PY_UTIME (enabled at basic features level) - MICROPY_PY_UTIME_GMTIME_LOCALTIME_MKTIME - MICROPY_PY_UTIME_TIME_TIME_NS Signed-off-by: Damien George <damien@micropython.org>
* all: Bump version to 1.20.0.v1.20.0Damien George2023-04-26
| | | | Signed-off-by: Damien George <damien@micropython.org>
* extmod/btstack: Fix indicate/notify queuing.Jim Mussared2023-04-26
| | | | | | | | | | | This adds a mechanism to track a pending notify/indicate operation that is deferred due to the send buffer being full. This uses a tracked alloc that is passed as the content arg to the callback. This replaces the previous mechanism that did this via the global pending op queue, shared with client read/write ops. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* py/makeqstrdefs.py: Fix handling GreenHills C/C++ preprocessor output.Alex Riesen2023-04-11
| | | | | | | | | | | | | The GreenHills preprocessor produces #line directives without a file name, which the regular expression used to distiguish between "# <number> file..." (GCC and similar) and "#line <number> file..." (Microsoft C and similar) does not match, aborting processing. Besides, the regular expression was unnecessarily wide, matching lines containing a "#", followed by any number of 'l','i','n', and 'e' characters. Signed-off-by: Alex Riesen <alexander.riesen@cetitec.com>
* py/obj: Fix spelling of staticmethod.David Lechner2023-03-28
| | | | Signed-off-by: David Lechner <david@pybricks.com>
* py/scheduler: Implement VM abort flag and mp_sched_vm_abort().Damien George2023-03-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is intended to be used by the very outer caller of the VM/runtime. It allows setting a top-level NLR handler that can be jumped to directly, in order to forcefully abort the VM/runtime. Enable using: #define MICROPY_ENABLE_VM_ABORT (1) Set up the handler at the top level using: nlr_buf_t nlr; nlr.ret_val = NULL; if (nlr_push(&nlr) == 0) { nlr_set_abort(&nlr); // call into the VM/runtime ... nlr_pop(); } else { if (nlr.ret_val == NULL) { // handle abort ... } else { // handle other exception that propagated to the top level ... } } nlr_set_abort(NULL); Schedule an abort, eg from an interrupt handler, using: mp_sched_vm_abort(); Signed-off-by: Damien George <damien@micropython.org>
* py/mpstate: Add mp_thread_is_main_thread() helper macro.Damien George2023-03-21
| | | | Signed-off-by: Damien George <damien@micropython.org>
* py/obj: Add MP_NOINLINE to mp_obj_malloc_helper.David Lechner2023-03-17
| | | | | | | | | | | As the comment in py/obj.h says: > Implementing this as a call rather than inline saves 8 bytes per usage. So in order to get this savings, we need to tell the compiler to never inline the function. Signed-off-by: David Lechner <david@pybricks.com>
* py/makeversionhdr.py: Always add micro to version string even if it's 0.Damien George2023-03-10
| | | | | | Moving forward, tags in this repository will always have three components. Signed-off-by: Damien George <damien@micropython.org>
* py/builtinimport: Fix unix port build with external imports disabled.Laurens Valk2023-03-10
| | | | | | | | Without this, building the unix port variants gives: ports/unix/main.c:667: undefined reference to `mp_obj_is_package', when MICROPY_ENABLE_EXTERNAL_IMPORT is 0. Signed-off-by: Laurens Valk <laurens@pybricks.com>
* py/mpconfig: Provide config option for internal printf printer.Damien George2023-03-10
| | | | | | | The C-level printf is usually used for internal debugging prints, and a port/board may want to redirect this somewhere other than stdout. Signed-off-by: Damien George <damien@micropython.org>
* py/gc: Make gc_dump_info/gc_dump_alloc_table take a printer as argument.Damien George2023-03-10
| | | | | | So that callers can redirect the output if needed. Signed-off-by: Damien George <damien@micropython.org>
* py/compile: Fix scope of assignment expression target in comprehensions.Damien George2023-03-09
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* py/makeversionhdr.py: Optionally get git tag and git hash from env vars.David Grayson2023-03-02
| | | | | | | This is handy when you are doing builds outside of the Git repository but still want to record that information. Signed-off-by: David Grayson <davidegrayson@gmail.com>
* py/emitnative: Explicitly compare comparison ops in binary_op emitter.Pepijn de Vos2023-02-27
| | | | | | | Without this it's possible to get a compiler error about the comparison always being true, because MP_BINARY_OP_LESS is 0. And it seems that gcc optimises these 6 equality comparisons into the same size machine code as before.