Create Firmware Stubs (formerly MCU stubs)¶
It is possible to create MicroPython firmware stubs using the stubber firmware-stubs command (the mcu-stubs alias is still accepted for backward compatibility).
For a complete end-to-end example that includes firmware stubs alongside doc stubs and frozen stubs, see the Quick Start guide.
Quick Examples¶
# Generate stubs for all connected MCUs
stubber firmware-stubs
# Generate stubs for specific serial port
stubber firmware-stubs --serial COM3
This command will do the following:
It determines the serial ports that are available on your system.
It runs a small script to determine the firmware family, the version and the port of the device, and looks up the board’s description in a list of known boards.
It uses
mpremote mipto install the files needed to generate the stubs on the device.It runs a variant of the
createstubs.pyscript on the device to generate the stubs.It cleans the stub folder.
It generates stubs, using a predetermined list of module names. For each found module or submodule a stub file is written to the device and progress is output to the console/REPL.
A module manifest (
modules.json) is created that contains the pertinent information determined from the board, the version of createstubs.py and a list of the successfully generated stubs.The generated stubs are downloaded to a folder on the PC, in a subfolder named after the firmware ID and version.
The stubs are post-processed using
stubgento format the stubs and generate the .pyi files.The stubs are enriched with typing information from the reference stubs where matching.
A new package is created in the publish folder ready for use in your IDE or publication to PyPI.
Module duplication
Due to the module naming convention in MicroPython some modules will be duplicated, i.e. uos and os will both be included.
Manual script usage (legacy / advanced)¶
Recommended: Use
stubber firmware-stubs— it automates all of the steps below (install, run, download, post-process).
The manual approach below is only needed for highly constrained boards or custom workflows where the automated command cannot be used.
The createstubs.py script can either be run as a script or imported as a module depending on your preferences.
Running as a script is used on the Linux or Win32 platforms in order to pass a –path parameter to the script.
The steps are:
Connect to your board.
Upload the script(s) to your board. All variants of the script are located in the
/boardfolder of this repo.Run/import the
createstubs.pyscript.Download the generated stubs to a folder on your PC.
Run the post-processor [optional, but recommended].
![createstubs-flow][]
Note: There is a memory allocation bug in MicroPython 1.13.0 that prevents createstubs.py from working. This was fixed in nightly build v1.13-103 and newer.
If you try to create stubs on the defective v1.13.0 version, the stubber will raise NotImplementedError(“MicroPython 1.13.0 cannot be stubbed”)
Generating Stubs for a specific Firmware¶
The stub files are generated on a MicroPython board by running the script {ref}createstubs.py logging module, you will need to upload this to your board, or use the minified version.
import createstubs
The generation will take a few minutes (2-5 minutes) depending on the speed of the board and the number of included modules.
As the stubs are generated on the board, and as MicroPython is highly optimized to deal with the scarce resources, this unfortunately does mean that the stubs lack parameter details. So for these you must still use the documentation provided for that firmware.
Downloading the files¶
After the stub files have been generated, you will need to download the generated stubs from the MicroPython board and most likely you will want to copy and save them in a folder on your computer. If you work with multiple firmwares, ports or versions it is simple to keep the stub files in a common folder as the firmware ID is used to generate unique names:
./stubs
/micropython-v1_10-stm32
/micropython-v1_12-esp32
/micropython-v1_11-linux
/loboris-v3_1_20-esp32
/loboris-v3_2_24-esp32
Custom firmware¶
The script tries to determine a firmware ID and version from the information provided in {ref}sys.implementation , `{ref}`sys.uname() <sysuname> and the existence of specific modules.
This firmware ID is used in the stubs, and in the folder name to store the stubs.
If you need, or prefer, to specify a firmware ID you can do so by setting the firmware_id variable before importing createstubs. For this you will need to edit the createstubs.py file.
The recommendation is to keep the firmware ID short, and add a version as in the below example.
# almost at the end of the file
def main():
stubber = Stubber(firmware_id='HoverBot v1.2.1')
# Add specific additional modules to be stubbed
stubber.add_modules(['hover','rudder'])
After this, upload the file and import it to generate the stubs using your custom firmware ID.
The Unstubbables¶
There are a limited number of modules that cannot be stubbed by createstubs.py for a number of different reasons. Some simply raise errors, others may reboot the MCU, or require a specific configuration or state before they are loaded.
A few of the frozen modules are just included as a sample rather than being useful to generate stubs for.
The problematic category throw errors or lock up the stubbing process altogether:
self.problematic=["upysh","webrepl_setup","http_client","http_client_ssl","http_server","http_server_ssl"]
The excluded category provides no relevant stub information:
self.excluded=["webrepl","_webrepl","port_diag","example_sub_led.py","example_pub_button.py"]
createstubs.py will not process a module in either category.
Note that some of these modules are also included in the frozen modules that are gathered for those ports or boards. For those modules it makes sense to use/prioritize the .pyi stubs for the frozen modules over the firmware stubs.