interpreters/python: Enable using pip to install Python packages

This commit enables using `pip` as a pre-compiled (pyc) built-in
distributed along with cpython.

Signed-off-by: Tiago Medicci <tiago.medicci@espressif.com>
This commit is contained in:
Tiago Medicci 2026-05-08 13:54:17 -03:00 committed by Matteo Golin
parent 2fce07fe1c
commit 8ba84edb0a
11 changed files with 313 additions and 12 deletions

View file

@ -0,0 +1,25 @@
--- a/Tools/wasm/wasm_assets.py
+++ b/Tools/wasm/wasm_assets.py
@@ -40,7 +40,6 @@ OMIT_FILES = (
# regression tests
"test/",
# package management
- "ensurepip/",
"venv/",
# other platforms
"_aix_support.py",
@@ -148,6 +147,13 @@ def create_stdlib_zip(
if entry.name.endswith(".py") or entry.is_dir():
# writepy() writes .pyc files (bytecode).
pzf.writepy(entry, filterfunc=filterfunc)
+
+ # Preserve ensurepip wheel payloads so `python -m ensurepip` can
+ # bootstrap pip on targets that consume this stdlib zip archive.
+ bundled_wheels = args.srcdir_lib / "ensurepip" / "_bundled"
+ if bundled_wheels.is_dir():
+ for wheel in sorted(bundled_wheels.glob("*.whl")):
+ pzf.write(wheel, arcname=f"ensurepip/_bundled/{wheel.name}")
def detect_extension_modules(args: argparse.Namespace) -> Dict[str, bool]:

View file

@ -0,0 +1,21 @@
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -1800,15 +1800,15 @@ static int
static const time_t YEAR = (365 * 24 + 6) * 3600;
time_t t;
struct tm p;
- time_t janzone_t, julyzone_t;
+ long long janzone_t, julyzone_t;
char janname[10], julyname[10];
t = (time((time_t *)0) / YEAR) * YEAR;
_PyTime_localtime(t, &p);
get_zone(janname, 9, &p);
- janzone_t = -get_gmtoff(t, &p);
+ janzone_t = -(long long)get_gmtoff(t, &p);
janname[9] = '\0';
t += YEAR/2;
_PyTime_localtime(t, &p);
get_zone(julyname, 9, &p);
- julyzone_t = -get_gmtoff(t, &p);
+ julyzone_t = -(long long)get_gmtoff(t, &p);
julyname[9] = '\0';

View file

@ -0,0 +1,35 @@
--- a/Tools/wasm/wasm_assets.py
+++ b/Tools/wasm/wasm_assets.py
@@ -47,13 +47,20 @@
# webbrowser
"antigravity.py",
"webbrowser.py",
- # Pure Python implementations of C extensions
- "_pydecimal.py",
+ # Pure Python implementations of C extensions.
+ # NOTE: keep "_pydecimal.py" so decimal.py can fall back to it when the
+ # _decimal C extension is not built (NuttX targets do not link libmpdec).
"_pyio.py",
# concurrent threading
"concurrent/futures/thread.py",
# Misc unused or large files
"pydoc_data/",
+ # Tooling/REPL extras not needed on a constrained embedded target.
+ "unittest/",
+ "_pyrepl/",
+ "idlelib/",
+ "turtledemo/",
+ "wsgiref/",
)
# Synchronous network I/O and protocols are not supported; for example,
@@ -80,7 +87,8 @@
"_asyncio": ["asyncio/"],
"_curses": ["curses/"],
"_ctypes": ["ctypes/"],
- "_decimal": ["decimal.py"],
+ # decimal.py is intentionally NOT omitted here: it ships a pure-Python
+ # fallback (_pydecimal) used when the _decimal C ext is unavailable.
"_dbm": ["dbm/ndbm.py"],
"_gdbm": ["dbm/gnu.py"],
"_json": ["json/"],

View file

@ -0,0 +1,25 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tiago Medicci <tiago.medicci@espressif.com>
Date: Thu, 7 May 2026 14:00:00 -0300
Subject: [PATCH] posixmodule: ignore chmod on NuttX like WASI
NuttX's tmpfs does not implement chstat, so chmod fails with ENOSYS.
Apply the same workaround already used for WASI: silently succeed
when HAVE_CHMOD is not defined.
---
Modules/posixmodule.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -3608,8 +3608,8 @@
#ifdef HAVE_CHMOD
result = chmod(path->narrow, mode);
-#elif defined(__wasi__)
- // WASI SDK 15.0 does not support chmod.
+#elif defined(__wasi__) || defined(__NuttX__)
+ // WASI SDK 15.0 and NuttX do not fully support chmod.
// Ignore missing syscall for now.
result = 0;
#else