1DOLLY 72PACKAGE python3REQUIRES HOST runtime@04REQUIRES HOST dso@05REQUIRES HOST http@06REQUIRES HOST sockets@07REQUIRES HOST threads@089FROM /v0.1.5/Dollyfile-system 87fe1e350c90556f41ae3e45343f9122ea9eca8cc488ae18b8a3ec08f1af098910USE /v0.1.5/Dollyfile-libdolly-sockets e629f66340342d53b4f5251cf02fd275198ce71ef11e884675003ad2a8f25fc111USE /v0.1.5/demos/tools/Dollyfile-sqlite 29afb422fd3306229324deb9c4d4237429287f2234cb9d215a5894abdf25e5ea12USE /v0.1.5/demos/tools/Dollyfile-bzip2 3d115d0cac539a5ea79cf7021b0023b49b6a4b5e095202fb3dd8a4630884573913USE /v0.1.5/demos/tools/Dollyfile-xz 81e23252e1f473a7ea097b4c0cd9fcd460af14ab79499417ce8bdcac5b33061e14# Build the Python runtime and native extension SDK; pip.dm adds pip.15REQUIRES HEADER curl16REQUIRES HEADER dso17REQUIRES HEADER libc18REQUIRES HEADER runtime19REQUIRES HEADER zlib20REQUIRES HEADER sqlite321REQUIRES HEADER bzlib22REQUIRES HEADER lzma23REQUIRES LIB    curl24REQUIRES LIB    z25REQUIRES LIB    sqlite326REQUIRES LIB    bz227REQUIRES LIB    lzma28REQUIRES TOOL   ar29REQUIRES TOOL   cc30REQUIRES TOOL   c++31REQUIRES TOOL   cp32REQUIRES TOOL   make33REQUIRES TOOL   mkdir34REQUIRES TOOL   mv35REQUIRES TOOL   rm36REQUIRES TOOL   tar37REQUIRES TOOL   test38REQUIRES TOOL   touch3940INSTALL /v0.1.5/demos/python/Dollyfile-libffi d8a7cebc28dc2c4ea4127c3eb866080a02bf4c817f425602567bff2a5acfed5f41EXPORTS LIB    ffi       /usr/lib/libffi.a42EXPORTS HEADER ffi       /usr/include/ffi.h43EXPORTS HEADER ffitarget /usr/include/ffitarget.h44FILE /usr/share/licenses/libffi/LICENSE45# python links the three USEd libraries statically and carries their licences.46FILE /usr/share/licenses/sqlite/blessing47FILE /usr/share/licenses/bzip2/LICENSE48FILE /usr/share/licenses/xz/COPYING49FILE /usr/share/licenses/xz/COPYING.0BSD50REQUIRES HEADER http51REQUIRES HEADER ffi52REQUIRES HEADER ffitarget53REQUIRES LIB    ffi54REQUIRES TOOL   gzip5556# Upstream Make runs the new interpreter before installing Lib. Do not retain57# timestamped bytecode caches from that build in the immutable image.58EXPORTS ENV PYTHONDONTWRITEBYTECODE 15960# The target is configured outside the browser, but every target object and61# executable is compiled here. Dolly-owned adapters remain independent pinned62# inputs instead of being hidden inside the upstream archive.63SOURCE /v0.1.5/dist/static/python/cpython.tar.gz 234e15e2b4a022716a70de30905088f0a9375e6983f435e36bd9b88cd15a03e6 /tmp/cpython.tar.gz6465SLOP gzip -dc /tmp/cpython.tar.gz | tar -xf - -C /6667SOURCE /v0.1.5/dist/static/python/runtimes/cpython-platform.c        20c5c120f835ce94ceb9be08cc25c4623ae333d844b2d3c3098ffed36f3b41eb /usr/src/python/Python/dolly_platform.c68SOURCE /v0.1.5/dist/static/python/runtimes/cpython-extension-check.c 1763ec04e582beee6066af81c93fe20e8cf0d83ae7d41d935b395c5cb3cdf071 /usr/src/python/Modules/dolly_extension_check.c69SOURCE /v0.1.5/dist/static/python/runtimes/cpython-socket-stubs.c    2aebdbdf3722dfa79f7b7eeb178b4beae2894a3d35ef12501054fb667342b335 /usr/src/python/Modules/dolly_socket_stubs.c70SOURCE /v0.1.5/dist/static/python/runtimes/cpython-http.c 13610f3322a4d09aa558e5d31523a082303835bf7c5981557c09443562cdc2da /usr/src/python/Modules/dolly_http.c71SOURCE /v0.1.5/dist/static/python/runtimes/cpython-transport.py 4567a855ff8459f6671c770dd69d93c84870bef3acd272f11ca28a394c9be92d /usr/src/python/Lib/_dolly_transport.py72SOURCE /v0.1.5/dist/static/python/runtimes/cpython-process.c         354dd7a01f1d16276d8478fdcb41bcb07da3078d6860ba52b423e059a32dd389 /usr/src/python/Modules/dolly_process.c73SOURCE /v0.1.5/dist/static/python/runtimes/cpython-subprocess.py     cabc2b4eb15e61332c2b63454724c3b390c5f2a2f0effa2889861e123835b785 /usr/src/python/Lib/_dolly_subprocess.py7475# The embedded LLVM optimizer spends minutes on a small measured set of76# translation units. Compile only those outliers at -O0 and let upstream Make77# preserve the prepared objects; the rest of CPython is substantially faster78# at -O2.79SLOP CWD /usr/src/python cc \80  -c \81  -O0 \82  -std=c11 \83  -fno-builtin \84  -fno-strict-aliasing \85  -IInclude/internal \86  -IInclude/internal/mimalloc \87  -IObjects \88  -IInclude \89  -IPython \90  -I. \91  -DPy_BUILD_CORE \92  Python/tracemalloc.c \93  -o Python/tracemalloc.o94SLOP CWD /usr/src/python cc \95  -c \96  -O0 \97  -std=c11 \98  -fno-builtin \99  -fno-strict-aliasing \100  -IInclude/internal \101  -IInclude/internal/mimalloc \102  -IObjects \103  -IInclude \104  -IPython \105  -I. \106  -DPy_BUILD_CORE \107  Modules/arraymodule.c \108  -o Modules/arraymodule.o109SLOP CWD /usr/src/python cc \110  -c \111  -O0 \112  -std=c11 \113  -IInclude/internal \114  -IInclude/internal/mimalloc \115  -IObjects \116  -IInclude \117  -IPython \118  -I. \119  -DPy_BUILD_CORE \120  Python/dolly_platform.c \121  -o Python/dolly_platform.o122SLOP CWD /usr/src/python cc \123  -c \124  -O0 \125  -std=c11 \126  -IInclude/internal \127  -IInclude/internal/mimalloc \128  -IObjects \129  -IInclude \130  -IPython \131  -I. \132  -DPy_BUILD_CORE \133  -DDATE='"Jan 01 1970"' \134  -DTIME='"00:00:00"' \135  Modules/getbuildinfo.c \136  -o Modules/getbuildinfo.o137SLOP CWD /usr/src/python cc \138  -c \139  -O0 \140  -std=c11 \141  -IInclude/internal \142  -IInclude/internal/mimalloc \143  -IObjects \144  -IInclude \145  -IPython \146  -I. \147  -DPy_BUILD_CORE \148  -DPLATFORM='"dolly"' \149  Python/getplatform.c \150  -o Python/getplatform.o151SLOP CWD /usr/src/python cc \152  -c \153  -O0 \154  -std=c11 \155  -IInclude/internal \156  -IInclude/internal/mimalloc \157  -IObjects \158  -IInclude \159  -IPython \160  -I. \161  -DPy_BUILD_CORE \162  -DABIFLAGS='""' \163  -DMULTIARCH='"dolly_0_wasm64"' \164  Python/sysmodule.c \165  -o Python/sysmodule.o166SLOP CWD /usr/src/python cc \167  -c \168  -O0 \169  -std=c17 \170  Modules/dolly_socket_stubs.c \171  -o Modules/dolly_socket_stubs.o172SLOP CWD /usr/src/python make \173  -o configure \174  -o config.status \175  -o Makefile.pre \176  -o Makefile \177  -o Modules/config.c \178  -o Modules/getbuildinfo.o \179  -o Python/getplatform.o \180  -o Python/sysmodule.o \181  -o Python/tracemalloc.o \182  -o Modules/arraymodule.o \183  python \184  libpython3.14.a \185  SHELL=/bin/slop \186  CC=cc \187  LINKCC=cc \188  AR=ar \189  BLDSHARED=cc\ -shared \190  INSTSONAME=libpython3.14.a \191  DYNLOADFILE=dynload_shlib.o \192  PY_CFLAGS=-O2\ -std=c11\ -fno-builtin\ -fno-strict-aliasing\ -pthread \193  PY_CFLAGS_NODIST= \194  PY_CPPFLAGS=-IInclude/internal\ -IInclude/internal/mimalloc\ -IObjects\ -IInclude\ -IPython\ -I. \195  CFLAGSFORSHARED= \196  PY_CORE_LDFLAGS=-pthread \197  LDFLAGS= \198  LINKFORSHARED=-rdynamic \199  MODULE_MATH_LDFLAGS= \200  MODULE_CMATH_LDFLAGS= \201  MODULE__STATISTICS_LDFLAGS= \202  MODULE__DATETIME_LDFLAGS= \203  MODULE_PYEXPAT_LDFLAGS=Modules/expat/libexpat.a \204  MODULE__SOCKET_CFLAGS=-Dfreeaddrinfo=dolly_py_freeaddrinfo\ -Dgai_strerror=dolly_py_gai_strerror\ -Dgetaddrinfo=dolly_py_getaddrinfo\ -Dgethostbyaddr=dolly_py_gethostbyaddr\ -Dgethostname=dolly_py_gethostname\ -Dgetnameinfo=dolly_py_getnameinfo\ -Dgetprotobyname=dolly_py_getprotobyname\ -Dgetservbyport=dolly_py_getservbyport\ -Dhtonl=dolly_py_htonl\ -Dif_freenameindex=dolly_py_if_freenameindex\ -Dif_indextoname=dolly_py_if_indextoname\ -Dif_nameindex=dolly_py_if_nameindex\ -Dif_nametoindex=dolly_py_if_nametoindex\ -Dinet_aton=dolly_py_inet_aton\ -Dinet_ntop=dolly_py_inet_ntop\ -Dinet_pton=dolly_py_inet_pton\ -Dntohl=dolly_py_ntohl\ -Dpoll=dolly_py_poll \205  MODULE_BINASCII_CFLAGS=-DUSE_ZLIB_CRC32 \206  MODULE_BINASCII_LDFLAGS=-lz \207  MODULE_ZLIB_CFLAGS= \208  MODULE_ZLIB_LDFLAGS=-lz \209  MODULE__CTYPES_CFLAGS=-DHAVE_FFI_PREP_CIF_VAR\ -DHAVE_FFI_PREP_CLOSURE_LOC\ -DHAVE_FFI_CLOSURE_ALLOC \210  MODULE__CTYPES_LDFLAGS=-lffi \211  LIBS=-ldolly-sockets \212  SYSLIBS= \213  LIBM= \214  LIBC= \215  SHLIBS= \216  MACHDEP_OBJS=Python/dolly_platform.o\ Modules/dolly_socket_stubs.o \217  DTRACE=218219# Install the standard-library contents into their final prefix.  Treat the220# destination as an installation directory explicitly: it may already exist221# in a composed image, and `mv SOURCE DESTINATION` would then create a nested222# `Lib` directory instead of the sys.path layout CPython requires.223SLOP mkdir \224  -p \225  /usr/lib/python3.14 \226  /usr/lib/python3.14/lib-dynload227SLOP cp \228  -R \229  /usr/src/python/Lib/. \230  /usr/lib/python3.14231SLOP test \232  -f \233  /usr/lib/python3.14/encodings/__init__.py234SLOP cp \235  /usr/src/python/libpython3.14.a \236  /usr/lib/libpython3.14.a237SLOP mv \238  /usr/src/python/python \239  /usr/bin/python240SLOP ln -sf python /usr/bin/python3241SLOP mkdir \242  -p \243  /usr/include/python3.14244SLOP cp \245  -R \246  /usr/src/python/Include/. \247  /usr/include/python3.14248SLOP cp \249  /usr/src/python/pyconfig.h \250  /usr/include/python3.14/pyconfig.h251SLOP CWD /usr/src/python slop \252  -c \253  'export _PYTHON_PROJECT_BASE=/usr/src/python; python -m sysconfig --generate-posix-vars'254SLOP cp \255  /usr/src/python/build/lib.dolly_0-wasm64-3.14/_sysconfigdata__dolly_dolly_0_wasm64.py \256  /usr/lib/python3.14/_sysconfigdata__dolly_dolly_0_wasm64.py257SLOP mkdir \258  -p \259  /usr/lib/python3.14/config-3.14-dolly_0_wasm64260SLOP cp \261  /usr/src/python/Makefile \262  /usr/lib/python3.14/config-3.14-dolly_0_wasm64/Makefile263# The check module is built as setuptools builds an extension: sysconfig's CC264# and CFLAGS compile it, its LDSHARED links it.265SLOP python -c 'import shlex, subprocess, sysconfig; flags = lambda name: shlex.split(sysconfig.get_config_var(name)); \266  subprocess.run(flags("CC") + flags("CFLAGS") + ["-I/usr/include/python3.14", "-c", "/usr/src/python/Modules/dolly_extension_check.c", "-o", "/tmp/dolly_extension_check.o"], check=True); \267  subprocess.run(flags("LDSHARED") + ["/tmp/dolly_extension_check.o", "-o", "/usr/lib/python3.14/lib-dynload/dolly_extension_check.cpython-314-dolly_0_wasm64.so"], check=True)'268269EXPORTS TOOL   python270EXPORTS TOOL   python3271EXPORTS ENV    PYTHONUTF8 1272EXPORTS LIB    python     /usr/lib/libpython3.14.a273EXPORTS HEADER python     /usr/include/python3.14274275SLOP python \276  --version277SLOP python \278  -c 'import pathlib; p = pathlib.Path("/tmp/python-check.txt"); p.write_text("PYTHON-WASM64"); assert p.read_text() == "PYTHON-WASM64"'279SLOP python \280  -c 'import dolly_extension_check; assert dolly_extension_check.answer() == 42'281SLOP python \282  -c 'import mmap, pathlib; p = pathlib.Path("/tmp/mmap-check"); p.write_bytes(b"DOLLY"); f = p.open("rb"); m = mmap.mmap(f.fileno(), 5, access=mmap.ACCESS_READ); assert m[:] == b"DOLLY"; m.madvise(mmap.MADV_SEQUENTIAL); m.close(); f.close()'283SLOP python \284  -c 'import sysconfig; assert sysconfig.get_platform() == "dolly_0-wasm64"; assert sysconfig.get_config_var("EXT_SUFFIX") == ".cpython-314-dolly_0_wasm64.so"'285SLOP python \286  -c 'import os, subprocess; assert subprocess.check_output(["echo", "spawn-ok"], text=True).strip() == "spawn-ok"; assert subprocess.check_output(["python", "-c", "print(6 * 7)"], text=True).strip() == "42"; child_env = dict(os.environ, DOLLY_CHILD_ENV="explicit"); assert subprocess.check_output(["python", "-c", "import os; print(os.environ[\"DOLLY_CHILD_ENV\"])"] , env=child_env, text=True, timeout=1).strip() == "explicit"'287# Threads run at once: two that wait on each other, a pool's three workers at288# a barrier, and a library and a closure used from a thread they were not made in.289SLOP python \290  -c 'import threading; started, answered = threading.Event(), threading.Event(); worker = threading.Thread(target=lambda: (started.set(), answered.wait(60))); worker.start(); assert started.wait(60); answered.set(); worker.join(60); assert not worker.is_alive()'291SLOP python \292  -c 'import threading; from concurrent.futures import ThreadPoolExecutor; barrier = threading.Barrier(3); pool = ThreadPoolExecutor(3); assert sorted(item.result(60) for item in [pool.submit(barrier.wait, 60) for n in range(3)]) == [0, 1, 2]; pool.shutdown()'293SLOP python \294  -c 'import ctypes, threading; callback = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)(lambda value: value + 1); seen = []; worker = threading.Thread(target=lambda: seen.extend([__import__("dolly_extension_check").answer(), callback(41)])); worker.start(); worker.join(); assert seen == [42, 42]'295SLOP python \296  -c 'import hashlib; assert hashlib.md5(b"abc", usedforsecurity=False).hexdigest() == "900150983cd24fb0d6963f7d28e17f72"'297SLOP python \298  -c 'import ctypes; libc = ctypes.CDLL(None); libc.strlen.argtypes = [ctypes.c_char_p]; libc.strlen.restype = ctypes.c_size_t; assert libc.strlen(b"dolly") == 5; callback_type = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int); callback = callback_type(lambda value: value + 1); assert callback(41) == 42'299SLOP python \300  -c 'import locale, sys; assert sys.flags.utf8_mode == 1; assert locale.getpreferredencoding(False).lower() == "utf-8"; assert sys.getfilesystemencoding().lower() == "utf-8"'301SLOP python \302  -c 'from pathlib import Path; p = Path("/tmp/python-header-check/check.cpp"); p.parent.mkdir(); p.write_text("#include <Python.h>\nint python_header_check = 42;\n", encoding="utf-8")'303SLOP c++ \304  -c \305  -std=c++17 \306  -I/usr/include/python3.14 \307  /tmp/python-header-check/check.cpp \308  -o /tmp/python-header-check/check.o309SLOP python \310  -c 'import os, sys, termios, tty; assert not os.isatty(0); assert sys.stdin.buffer.read(1) == b""'311# A C++ thread_local with a destructor registers it through pthread_key_create312# (SciPy's _uarray), which the thread stubs refused with a fatal error.313SLOP python \314  -c 'from pathlib import Path; p = Path("/tmp/python-tls/tls.cpp"); p.parent.mkdir(); p.write_text("#include <string>\nstatic thread_local std::string name(\"dolly\");\nextern \"C\" int tls_length() { return int(name.size()); }\n", encoding="utf-8")'315SLOP c++ -shared /tmp/python-tls/tls.cpp -o /tmp/python-tls/tls.so316SLOP python -c 'import ctypes; assert ctypes.CDLL("/tmp/python-tls/tls.so").tls_length() == 5'317318FILE /usr/share/licenses/cpython/LICENSE319# The PSF License Agreement asks derivatives to summarize their changes.320FILE /usr/share/licenses/cpython/DOLLY-CHANGES321    Dolly's changes to CPython: cpython-dolly.patch ports posixmodule, getpath,322    faulthandler, subprocess, site, platform, sysconfig, uuid, ctypes.util and323    the pager to sys.platform "dolly", where processes use Dolly's spawn and324    wait and there is no fork. Built-in modules added by Dolly carry HTTP through the325    browser's broker (_dolly_http, _dolly_transport), fail name resolution326    and ssl explicitly, and run libffi over process-local calls. The patched source is327    published beside this image as dist/static/python/cpython.tar.gz.328EXPORTS FOLDER python-stdlib /usr/lib/python3.14329330SLOP rm \331  -rf \332  /tmp/cpython.tar.gz \333  /tmp/mmap-check \334  /tmp/python \335  /tmp/python-header-check \336  /tmp/python-check.txt \337  /usr/lib/python3.14/test \338  /usr/src/python339REQUIRES TOOL python340341# CPython's bundled pip, installed offline without build-time bytecode.342SLOP python \343  /usr/lib/python3.14/ensurepip/_bundled/pip-26.2.1-py3-none-any.whl/pip \344  install \345  --no-compile \346  --no-index \347  --disable-pip-version-check \348  --root-user-action=ignore \349  /usr/lib/python3.14/ensurepip/_bundled/pip-26.2.1-py3-none-any.whl350FOLDER /usr/lib/python3.14/site-packages351EXPORTS TOOL pip352EXPORTS TOOL pip3353354# pip builds what has no wheel for Dolly, which is every native package: a C355# extension with the compiler, a Meson project such as NumPy with Ninja too.356INSTALL /v0.1.5/Dollyfile-cc afd89a983721972cb610d1d03ea39d5e6123d50b7b1a2b6922f1265657cc286a357358# The browser policy decides which indexes are reachable; skip pip's own359# PyPI version check. Dolly has one user, uid 0. sdists build as upstream360# builds its wheels: NumPy's release build takes as long as its debug build361# (141 s, 2026-11-03).362FILE /etc/pip.conf363    [global]364    disable-pip-version-check = true365    root-user-action = ignore366367SLOP python \368  -c 'import urllib.request; assert urllib.request.HTTPHandler.__module__ == "_dolly_transport"'369SLOP pip \370  --version371FILE /usr/share/man/cat1/python3.1372    python3, python, pip: CPython and pip, with the cc package pip builds native373    packages with.374    375      python3 SCRIPT          runs a script; python3 alone, the prompt376      pip install PACKAGE     installs a wheel or builds an sdist377    378    An sdist with C code is compiled by cc. One built with Meson (NumPy,379    Pandas) needs Ninja too: amy install ninja. pip's settings are in380    /etc/pip.conf. urllib.request and requests send through the page's HTTP381    broker and its policy. sys.platform is "dolly"; Emscripten and Pyodide382    wheels do not fit it. Upstream's documentation: https://docs.python.org/3/383