In commit 86ce4426079b1b368881c22f46d80045e2f720b0 the '.frozen' entry was
added at the start of sys.path, to allow control over when frozen modules
are searched during import, and retain existing behaviour whereby frozen
was searched before the filesystem.
But Python semantics of sys.path require sys.path[0] to be the directory of
the currently executing script, or ''.
This commit moves the '.frozen' entry to second place in sys.path, so
sys.path[0] retains its correct value (described above).
Signed-off-by: Damien George <damien@micropython.org>
This commit makes sure that the value zero is always encoded in an mpz_t as
neg=0 and len=0 (previously it was just len=0).
This invariant is needed for some of the bitwise operations that operate on
negative numbers, because they cannot handle -0. For example
(-((1<<100)-(1<<100)))|1 was being computed as -65535, instead of 1.
Fixes issue #8042.
Signed-off-by: Damien George <damien@micropython.org>
The mp_sys_path_obj and mp_sys_argv_obj objects are only used by the
runtime and accessible from Python if MICROPY_PY_SYS is enabled. So
exclude them from the runtime state if this option is disabled.
Signed-off-by: Damien George <damien@micropython.org>
If MICROPY_PY_SYS_PATH_ARGV_DEFAULTS is enabled (which it is by default)
then sys.path and sys.argv will be initialised and populated with default
values. This keeps all bare-metal ports aligned.
Signed-off-by: Damien George <damien@micropython.org>
This ensures MICROPY_QSTR_EXTRA_POOL and MICROPY_MODULE_FROZEN_MPY are set
if necessary before the CFLAGS are extracted for QSTR generation.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This changes makemanifest.py & mpy-tool.py to merge string and mpy names
into the same list (now mp_frozen_names).
The various paths for loading a frozen module (mp_find_frozen_module) and
checking existence of a frozen module (mp_frozen_stat) use a common
function that searches this list.
In addition, the frozen lookup will now only take place if the path starts
with ".frozen", which needs to be added to sys.path.
This fixes issues #1804, #2322, #3509, #6419.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This feature is not enabled on any port, it's not in CPython's io module,
and functionality is better suited to the micropython-lib implementation of
pkg_resources.
This targets the 64-bit CPU Raspberry Pis. The BCM2711 on the Pi 4
and the BCM2837 on the Pi 3 and Zero 2W. There are 64-bit fixes
outside of the ports directory for it.
There are a couple other cleanups that were incidental:
* Use const mcu_pin_obj_t instead of omitting the const. The structs
themselves are const because they are in ROM.
* Use PTR <-> OBJ conversions in more places. They were found when
mp_obj_t was set to an integer type rather than pointer.
* Optimize submodule checkout because the Pi submodules are heavy
and unnecessary for the vast majority of builds.
Fixes#4314
Make it possible to proceed to a regular lookup in locals_dict if the
custom type->attr fails. This allows type->attr to extend rather than
completely replace the lookup in locals_dict.
This is useful for custom builtin classes that have mostly regular methods
but just a few special attributes/properties. This way, type->attr needs
to deal with the special cases only and the default lookup will be used for
generic methods.
Signed-off-by: Laurens Valk <laurens@pybricks.com>
By having a pair of buffers, the capture hardware can fill one buffer while
Python code (including displayio, etc) operates on the other buffer. This
increases the responsiveness of camera-using code.
On the Kaluga it makes the following improvements:
* 320x240 viewfinder at 30fps instead of 15fps using directio
* 240x240 animated gif capture at 10fps instead of 7.5fps
As discussed at length on Discord, the "usual end user" code will look like
this:
camera = ...
with camera.continuous_capture(buffer1, buffer2) as capture:
for frame in capture:
# Do something with frame
However, rather than presenting a context manager, the core code consists of
three new functions to start & stop continuous capture, and to get the next
frame. The reason is twofold. First, it's simply easier to implement the
context manager object in pure Python. Second, for more advanced usage, the
context manager may be too limiting, and it's easier to iterate on the right
design in Python code. In particular, I noticed that adapting the
JPEG-capturing programs to use continuous capture mode needed a change in
program structure.
The camera app was structured as
```python
while True:
if shutter button was just pressed:
capture a jpeg frame
else:
update the viewfinder
```
However, "capture a jpeg frame" needs to (A) switch the camera settings and (B)
capture into a different, larger buffer then (C) return to the earlier
settings. This can't be done during continuous capture mode. So just
restructuring it as follows isn't going to work:
```python
with camera.continuous_capture(buffer1, buffer2) as capture:
for frame in capture:
if shutter button was just pressed:
capture a jpeg frame, without disturbing continuous capture mode
else:
update the viewfinder
```
The continuous mode is only implemented in the espressif port; others
will throw an exception if the associated methods are invoked. It's not
impossible to implement there, just not a priority, since these micros don't
have enough RAM for two framebuffer copies at any resonable sizes.
The capture code, including single-shot capture, now take mp_obj_t in the
common-hal layer, instead of a buffer & length. This was done for the
continuous capture mode because it has to identify & return to the user the
proper Python object representing the original buffer. In the Espressif port,
it was convenient to implement single capture in terms of a multi-capture,
which is why I changed the singleshot routine's signature too.
New design:
* capture output to a vstr
* compare the complete vstr to boot_out.txt
* rewrite if not a complete match
This is resilient against future changes to the automatic
text written to boot_out.txt.
This also fixes rewriting boot_out.txt in the case where
boot.py prints something.
Perhaps it also saves a bit of code space. Some tricks:
* no need to close a file in read mode
* no need to switch on/off USB write access, going down to the
oofatfs layer doesn't check it anyway
This makes it possible for cooperative multitasking systems to keep running
event loops during garbage collector operations.
For example, this can be used to ensure that a motor control loop runs
approximately each 5 ms. Without this hook, the loop time can jump to
about 15 ms.
Addresses #3475.
Signed-off-by: Laurens Valk <laurens@pybricks.com>
This is an stm32-specific feature that's accessed via the pyb module, so
not something that will be widely enabled.
Signed-off-by: Damien George <damien@micropython.org>
Some of these will later be moved to CORE or BASIC, but EXTRA is a good
starting point based on what stm32 uses.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This involves:
* Adding a new "L8" colorspace for colorconverters
* factoring out displayio_colorconverter_convert_pixel
* Making a minimal "colorspace only" version of displayio for the
unix port (testing purposes)
* fixing an error message
I only tested writing B&W animated images, with the following script:
```python
import displayio
import gifio
with gifio.GifWriter("foo.gif", 64, 64, displayio.Colorspace.L8) as g:
for i in range(0, 256, 14):
data = bytes([i, 255-i] * 32 + [255-i, i] * 32) * 32
print("add_frame")
g.add_frame(data)
# expected to raise an error, buffer is not big enough
with gifio.GifWriter("/dev/null", 64, 64, displayio.Colorspace.L8) as g:
g.add_frame(bytes([3,3,3]))
```
Before this, "%c" % 3.14 would raise the error `integer required`
even though python3 uses `%c requires int or char`, just like both
already did for "%c" % "ab".
This gets rid of a string to translate, and makes behavior match
python3 better.