Skip to content

WIP: Python/PyPI packaging for Unix port#19425

Open
jonnor wants to merge 3 commits into
micropython:masterfrom
jonnor:unix-python-package-1
Open

WIP: Python/PyPI packaging for Unix port#19425
jonnor wants to merge 3 commits into
micropython:masterfrom
jonnor:unix-python-package-1

Conversation

@jonnor

@jonnor jonnor commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Builds a Python package for Unix port, and sets up MicroPython.

This is an early version. High-level feedback and review comments are very welcomed. Once the overall approach is agreed on, I will clean it up accordingly.

Suggested next steps:

  • Unify naming of the various files - I propose to use micropython_unix.
  • Make the check.py file into a basic testcase, and run this for each and every wheel (cibuildwheel has support for this)

Prebuilt packages are available via pip install jonnor-micropython-unix. For Mac OS (ARM) and Linux (x86_64). It should work on Windows Subsystem for Linux using the Linux packages. I chose to support CPython 3.10+ (2021). I believe this is a practical starting point in terms of coverage, that should cover the majority of users.

It is possible to build and install the package from source by doing pip install "git+https://github.com/jonnor/micropython.git@unix-python-package-1#subdirectory=ports/unix". This requires build tools such as make and a compiler.

Testing

Tested installing the built package a couple of different Linux distributions.

  • Ubuntu 22.04, 24.04
  • CentOS 9 (with Python 3.12)
  • Arch Linux (current as of July 2026)
  • Fedora 44
  • Alpine with MUSL libc (current as of July 2026)
  • Pyodide (browser) using Jupyter Lite

To be tested: Windows Subsystem for Linux, Mac OS

Generative AI

I used generative AI tools when creating this PR, but a human has checked the
code and is responsible for the code and the description above.

Details: I did not use any code as-is from gen AI. It was primarily used for searching for information online, and for trying to understand some compile error messages.

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown

Code size report:

Reference:  py/py.mk: Move MICROPY_FORCE_32BIT to the Windows port's Makefile. [13303f8]
Comparison: ports/unix: Add Python package setup [merge of a197a8e]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:   +40 +0.005% standard
      stm32:    +0 +0.000% PYBV10
      esp32:    +0 +0.000% ESP32_GENERIC
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

Comment thread .github/workflows/ports_unix_python.yml Outdated
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not Windows too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unix port does not work on Windows, I think? At least there were some compile errors when I had it enabled - I just skipped it to focus on the other platforms first.

@Josverl Josverl Jul 5, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then perhaps not use the _unix suffix in the package name as that prohibits future platforms

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Josverl I am open for either! I don't really know Windows port much. But if it is sufficiently similar conceptually then a "micropython" package could make sense.

return ret;
}

PYBIND11_MODULE(micropython_run, m) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using pybind11 for a wrapper to call an executable seems quite heavy. Why not just use the subprocess module to call it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The specific reason is for Pyodide, the packaging target that allows this in browser - specifically for Jupyter Lite (Jupyter Lab in browser). That environment does not have processes, so the MicroPython interpreter must execute "in process". That is a key feature for me - since I want to teach machine learning for MicroPython, where participants need both CPython (for training ML models) and MicroPython (for the on-device code) - and Jupyter Lite will enable a zero-install experience for that.

I have done a succesful proof-of-concept for that before. Will add that here also (can be in this MR or as a follow-up). Just requires a bit more fiddling with the build configuration and Emscripten toolchain, so I did not want to block the initial RFC on it :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module-approach also would make possible a proper API for the MicroPython interpreter.

vm = micropython_unix.Interpreter()
vm.execute("a = 1;  b=2; c=a+b")
c = vm.locals['c']

This is not an important usecase for me*, but might be of interest to others? Out-of-scope for now though!

*In combined CPython+MicroPython ML/DS dataflows I use scripts in MicroPython that take standardized files in and out, and then a wrapper in CPython that handles serialization etc. Which one can also use for on-device tests, and serialization overhead is not an issue.

@agatti agatti Jul 5, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module-approach also would make possible a proper API for the MicroPython interpreter.

With the right set of compilation flags and if it can be packaged as a shared library, this could - in theory - be used to replace most of mpy-cross C code via ctypes :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The specific reason is for Pyodide, the packaging target that allows this in browser

Would you not want to use the javascript port of MicroPython in this case?

Comment thread ports/unix/mpconfigport.mk Outdated
Comment thread ports/unix/setup.py
Comment thread .github/workflows/ports_unix_python.yml Outdated
jonnor added 3 commits July 5, 2026 15:54
Allows it to be used by other programs/modules,
such as a CPython module for running code
emscripten fails if this is present
Builds a Python package that provides a "micropython" script.
Can then be easily distributed on PyPi.
@jonnor jonnor force-pushed the unix-python-package-1 branch from 8db5831 to a197a8e Compare July 5, 2026 13:56
@jonnor

jonnor commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Thanks a lot for review feedback @dlech and @agatti ! I did a pass today and was able to resolve multiple of them.

I got the packages working with musllinux (Alpine). And I got it working in browser - Pyodide with Jupyter Lite. So now one can go to https://jupyter.org/try-jupyter/lab/ and do like the following to run MicroPython code:

# Install the package
import micropip
await micropip.install('jonnor-micropython-unix')

# Run some MicroPython code
import micropython_unix

code = """
# Example MicroPython code
import sys
import json

out_file = 'out2.txt'
with open(out_file, 'w') as f:
    o = sys.implementation
    s = json.dumps(dict(info=repr(o)))
    f.write(s)
"""

ret = micropython_unix.run_main(['micropython', '-c', code])
print(ret) # should be 0

# Check that output was written
with open("out2.txt") as f:
    print(f.read())

@Josverl

Josverl commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

To be tested:

  • Windows Subsystem for Linux

Tested:

  • MicroPython 9458e3a on 2026-07-05
  • WSL2 2.7.8.0
    1032 tests passed - 84 tests skipped

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants