Compare commits

...
1 Commits
Author SHA1 Message Date
thePR0M3TH3ANandClaude Opus 4.6 b5ab447207 fix(cli): set PYTHONNOUSERSITE=1 for onionshare-cli subprocess, robust cleanup (v0.2.19)
Root cause: user-local werkzeug 2.0.3 in ~/.local/lib/python3.11/
site-packages shadows the system werkzeug 2.2.2, breaking Flask's
LocalProxy.unbound_message for the system onionshare-cli.

The pip3 show-based cleanup was unreliable (shows system package,
skips user-local). Two-pronged fix:

1. Set PYTHONNOUSERSITE=1 in the env passed to onionshare-cli so it
   never loads packages from ~/.local — uses only system packages.
2. Install script now directly rm -rf's conflicting packages from
   ~/.local/lib/python3.*/site-packages/ instead of relying on pip3.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-03-16 10:14:39 -04:00
4 changed files with 18 additions and 20 deletions

No files matched your search

+9 -18
View File
@@ -97,26 +97,17 @@ else
fi
# Clean up stale user-local packages from prior pip --user installs of voxvera.
# These can shadow system packages (e.g. Werkzeug) and break onionshare-cli.
# These shadow system packages (e.g. Werkzeug) and break onionshare-cli.
msg "Cleaning up stale user-local packages that may conflict with system onionshare-cli..."
PIP_CLEANUP_OPTS=""
if [ -f /etc/debian_version ]; then
DEB_VER=$(cat /etc/debian_version | cut -d. -f1)
if [[ "$DEB_VER" =~ ^[0-9]+$ ]] && [ "$DEB_VER" -ge 12 ]; then
PIP_CLEANUP_OPTS="--break-system-packages"
fi
fi
for pkg in werkzeug flask flask-socketio onionshare-cli; do
if pip3 show --quiet "$pkg" 2>/dev/null && \
pip3 show "$pkg" 2>/dev/null | grep -q "Location.*\.local"; then
pip3 uninstall -y $PIP_CLEANUP_OPTS "$pkg" 2>/dev/null || true
fi
for pydir in "$HOME"/.local/lib/python3.*/site-packages; do
[ -d "$pydir" ] || continue
for pkg in werkzeug flask flask_socketio onionshare_cli voxvera; do
if [ -d "$pydir/$pkg" ]; then
warn "Removing stale $pkg from $pydir"
rm -rf "$pydir/$pkg" "$pydir/${pkg}-"*.dist-info 2>/dev/null || true
fi
done
done
# Also uninstall any previous pip --user install of voxvera itself
if pip3 show --quiet voxvera 2>/dev/null && \
pip3 show voxvera 2>/dev/null | grep -q "Location.*\.local"; then
pip3 uninstall -y $PIP_CLEANUP_OPTS voxvera 2>/dev/null || true
fi
download_binary() {
local url=$1
+1 -1
View File
@@ -14,7 +14,7 @@ voxvera = ["templates/**", "src/**", "resources/**", "locales/**", "resources/bi
[project]
name = "voxvera"
version = "0.2.18"
version = "0.2.19"
description = "VoxVera CLI utilities"
readme = "README.md"
authors = [{name = "VoxVera"}]
+1 -1
View File
@@ -1,7 +1,7 @@
import sys
from pathlib import Path
__version__ = "0.2.18"
__version__ = "0.2.19"
# Add the vendor directory to sys.path ONLY for PyInstaller (frozen) builds.
# For pip/pipx installs the system/venv packages are correct and the vendored
+7
View File
@@ -676,6 +676,9 @@ def _internal_onionshare():
# Always prefer the system onionshare-cli binary. This avoids
# pkg_resources / setuptools isolation issues in both PyInstaller
# builds and pipx venvs.
# Prevent user-local pip packages from shadowing system packages
os.environ["PYTHONNOUSERSITE"] = "1"
onionshare_bin = shutil.which("onionshare-cli") or shutil.which("onionshare")
if onionshare_bin:
os.execvp(onionshare_bin, [onionshare_bin] + onionshare_args)
@@ -706,6 +709,10 @@ def serve(config_path: str) -> str | None:
env = os.environ.copy()
env["TOR_SOCKS_PORT"] = socks
env["TOR_CONTROL_PORT"] = ctl
# Prevent user-local pip packages (~/.local) from shadowing system packages.
# onionshare-cli depends on specific Flask/Werkzeug versions from the system;
# stale user-local copies break it.
env["PYTHONNOUSERSITE"] = "1"
onionshare_args = [
"--website",