Skip to content

fix(cookbook): recognize runtime --user installs by replaying user-site .pth hooks#4811

Open
devpedrobarbosa wants to merge 2 commits into
pewdiepie-archdaemon:devfrom
devpedrobarbosa:fix/cookbook-runtime-user-install-pth-hooks
Open

fix(cookbook): recognize runtime --user installs by replaying user-site .pth hooks#4811
devpedrobarbosa wants to merge 2 commits into
pewdiepie-archdaemon:devfrom
devpedrobarbosa:fix/cookbook-runtime-user-install-pth-hooks

Conversation

@devpedrobarbosa

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #4694. The Real-ESRGAN build now succeeds, but the dependency was still shown as not installed in Cookbook → Dependencies, and a browser hard refresh never fixed it — only a full container restart did.

Root cause: the local optional-dep probe in list_packages decides "installed" by importing the package in-process. Cookbook installs optional deps with pip install --user, so the package lands in user-site along with setuptools' distutils-precedence.pth. On Python 3.12+ distutils is gone from the stdlib and is only restored by that .pth. When the dep is installed into an already-running server, user-site was never processed by site; the recovery used sys.path.append(user_site), which makes modules importable but does not execute user-site .pth files. So import basicsr (a realesrgan dep) → import distutils raised ModuleNotFoundError: No module named 'distutils', the probe caught it as ImportError, and realesrgan read as not-installed until a process restart.

Fix: use site.addsitedir(user_site) instead of sys.path.append(user_site) so user-site .pth hooks (incl. the setuptools distutils shim) are replayed when a package is installed into a running process.

Target branch

  • This PR targets dev, not main.

Linked Issue

Fixes #4810

Type of Change

  • Bug fix (non-breaking — fixes a confirmed issue)
  • New feature (non-breaking — adds new behaviour)
  • Breaking change (changes or removes existing behaviour)
  • Refactor / cleanup (behaviour unchanged)
  • Documentation only
  • CI / tooling / configuration

Checklist

  • I searched open issues and open PRs — this is not a duplicate.
  • This PR targets dev
  • My changes are limited to the scope described above — no unrelated refactors or whitespace changes mixed in.
  • I actually ran the app (docker compose up) and verified the change works end-to-end. Type-checks and unit tests are not enough.

How to Test

On the python:3.14 image (docker compose up -d --build):

  1. Reproduce (before this PR): with the server already running, install realesrgan from Cookbook → Dependencies. It builds/installs (importlib.metadata.version("realesrgan") == "0.3.0"), but the panel still shows it not installed, and a hard refresh doesn't help. Confirmed the in-process probe path fails:
    docker compose exec -u odysseus odysseus python -s -c \
      'import sys,site; sys.path.append(site.getusersitepackages()); import realesrgan'
    # ModuleNotFoundError: No module named 'distutils'
  2. With this PR: the same probe path uses site.addsitedir(...) and resolves:
    docker compose exec -u odysseus odysseus python -s -c \
      'import sys,site; site.addsitedir(site.getusersitepackages()); import realesrgan; print("ok")'
    # ok
  3. Verify recognition: reload the Dependencies panel — realesrgan shows installed without a restart. Confirmed via the exact local-probe path:
    docker compose exec -u odysseus odysseus python -c \
      'from src.optional_deps import prepare_optional_dependency_import as p; \
       import importlib, importlib.metadata as m; p("realesrgan"); \
       importlib.import_module("realesrgan"); print(m.version("realesrgan"))'
    # 0.3.0
  4. Confirm the .pth is user-site only: distutils-precedence.pth exists in /app/.local/lib/python3.14/site-packages/ but not in the main site-packages — which is why a plain sys.path.append left distutils unavailable.

Visual / UI changes — REQUIRED if you touched anything that renders

N/A — no UI/rendering changes. Touches only routes/shell_routes.py (one line in the list_packages user-site prologue, plus an explanatory comment).

Local optional-dep probing in `list_packages` decides "installed" by
importing the package in-process. When a dep is installed at runtime via
Cookbook -> Dependencies (`pip install --user`) into a long-lived server
that started before the install, user-site was never processed by `site`.

The recovery used `sys.path.append(user_site)`, which makes modules
importable but does NOT execute user-site `.pth` files. On Python 3.12+
`distutils` is gone from the stdlib and is only restored by setuptools'
`distutils-precedence.pth` (shipped in user-site). basicsr (a realesrgan
dep) does `import distutils` at import time, so the probe failed with
`ModuleNotFoundError: No module named 'distutils'` and reported realesrgan
as not installed until a full restart.

Use `site.addsitedir(user_site)` instead so user-site `.pth` hooks are
replayed and the distutils shim activates. Verified end-to-end on the
python:3.14 image: realesrgan now probes as installed without a restart.

Fixes pewdiepie-archdaemon#4810

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added the ready for review Description complete — ready for maintainer review label Jun 24, 2026
The regression test pinned the old `sys.path.append(user_site)` source
text. Update it to assert the new `site.addsitedir(user_site)` guarantee
that user-site `.pth` hooks are replayed for runtime --user installs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for review Description complete — ready for maintainer review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cookbook: realesrgan installs but is not recognized — runtime --user installs don't replay user-site .pth hooks (distutils shim)

1 participant