Skip to content

Support distro-packaged Python environments (read-only sys.executable) #5427

@JamieMagee

Description

@JamieMagee

PlatformIO is packaged by several Linux distributions (NixOS, Guix, Arch, Fedora, etc.). Distro packages install PlatformIO into a read-only Python environment where sys.executable points to an interpreter that can't be written to by pip install.

This causes a few problems that distro maintainers currently work around with patches:

  1. upgrade.py runs pip install --upgrade against a read-only interpreter

commands/upgrade.py calls pip install --upgrade using get_pythonexe_path(). On distro installs, this fails because the site-packages directory is in a read-only store. An env var like PLATFORMIO_DISABLE_SELF_UPDATE=1 (or detecting a read-only prefix) would let distro packages skip this cleanly.

  1. copy_pythonpath_to_osenv() filters paths by looking for click/ or platformio/ directories

proc.py only adds sys.path entries to PYTHONPATH if they contain a click or platformio subdirectory. Distro packages install each dependency in its own prefix (e.g., NixOS has one store path per package), so this heuristic drops most of them. The SCons subprocess then can't import PlatformIO's dependencies.

NixOS patches this to just use sys.path directly. Would you accept a change that uses sys.path unconditionally on Linux, or respects an existing PYTHONPATH when set?

  1. Framework build scripts (esp-idf, Zephyr) assume they can pip install into sys.executable's environment

This isn't PlatformIO's code directly, but PlatformIO controls which Python the frameworks see. If get_pythonexe_path() could point to a writable venv that inherits the system packages (via --system-site-packages), frameworks could install their deps there without touching the system Python.

Would you consider supporting a PLATFORMIO_PYTHON_VENV env var? If set, PlatformIO would create a venv at that path (or reuse an existing one) and use it as the Python for builds. This would let PlatformIO and its frameworks install deps freely while the base installation stays read-only.


For context, NixOS currently carries a bunch of patches against platformio-core to work around these issues, plus wraps the whole thing in a bubblewrap FHS chroot. I'd rather reduce that patch surface if there's a way to do it that works for you too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions