Commit graph

2 commits

Author SHA1 Message Date
Wasim Yousef Said
72ab966221
Installer: suppress macOS uv developer tools dialog (#8479)
* Desktop: stop the loopback client following redirects

`loopback_http::client` is the client that posts `.desktop_secret` to
/api/auth/desktop-login, and it was built without a redirect policy. reqwest
follows up to 10 redirects by default, and its cross-host protection strips
headers rather than bodies, so a responder answering 307 (which preserves the
method and the body) would carry the secret to whatever the Location header
names, after the loopback URL had already been checked.

Its sibling `streaming_client` already refuses redirects for exactly this
reason: "Redirects are refused so a loopback URL cannot be bounced off-host
after the check." Give `client` the same policy.

No behaviour change for any real backend, which never redirects these routes.

* Suppress macOS uv developer tools dialog

* Update workspace guard for uv wrapper

* Stop the installer raising the macOS command line developer tools dialog

On a Mac without the Command Line Tools, /usr/bin/git, lipo, install_name_tool
and friends are libxcselect shims. Executing one resolves no developer dir and
posts to com.apple.dt.CommandLineTools.installondemand, which draws the
'requires the command line developer tools' dialog naming the tool. Resolving
the path does not; only execution does.

Two call sites execute a shim on the consumer path:

_has_working_git ran 'git --version' to decide whether git works, so on a clean
Mac the probe raised the dialog it exists to detect. It now answers from the
resolved path when that path is exactly /usr/bin/git and no toolchain is
selected. Deliberately narrow: a Homebrew, MacPorts or Xcode.app git earlier on
PATH is a real binary and is still probed by executing it, so a Mac with a
working git but no CLT selected behaves exactly as before. An earlier version of
this gated on 'no CLT implies no working git' and broke that case, which the
existing test caught. xcode-select -p only asks which toolchain is selected and
never prompts.

The venv arch probe called lipo first and fell back to file -L. lipo is a shim;
2>/dev/null hides its stderr but not a GUI dialog. file is base system and
always answers, so the order is swapped. Both spellings feed the same case
below, against 'Mach-O 64-bit executable arm64' or 'universal binary ...
[x86_64] [arm64]' rather than lipo's 'arm64' / 'x86_64 arm64', so the branch
taken is unchanged. clean-machine-assert.sh already made this same swap for its
own use.

The cctools binaries were missing from the clean machine CI tool list, so none
of this was visible: trace mode generated no wrapper and the absent list never
checked them. install_name_tool, lipo, otool, objdump, vtool, strip and nm are
added, which is what makes these fixes regression testable.

test_macos_clt_gate.sh gains two cases pinning the contract: with a shim git and
no toolchain selected the probe answers no WITHOUT executing it, proven by a
stub that records execution into a marker file, and with a real git elsewhere on
PATH the stub IS executed. The first assertion passed vacuously when written
(wrong temp path meant the marker could never be created) and was fixed by
making its pair fail first. 18 to 23 passing.

* Preserve working git on Intel macOS

* Keep the git shim guard on under Rosetta

---------

Co-authored-by: danielhanchen <unslothai@gmail.com>
Co-authored-by: danielhanchen <danielhanchen@users.noreply.github.com>
Co-authored-by: danielhanchen <danielhanchen@gmail.com>
2026-08-11 12:19:30 -07:00
Daniel Han
976a1152ad
Ask uv for a Python that can import torch, and skip the one that cannot (#7830)
* Ask uv for a Python that can import torch, and skip the one that cannot

Fixes #7803.

CPython 3.13.8 carries python/cpython#139783: inspect.getsourcelines() drops a
function body when a decorator is followed by a comment. That is the shape of
the @_overload_method blocks in torch 2.11's nn/modules/rnn.py, which are parsed
at import time, so `import torch` dies with IndentationError. 3.13.9 was an
expedited release carrying only that fix.

install.sh asked uv for a bare "3.13" and let it choose the patch. Measured with
uv 0.9.2 and only 3.13.8 present:

  --python 3.13             -> 3.13.8    then import torch: IndentationError
  --python >=3.13.9,<3.14   -> 3.13.12   then import torch: 2.11.0+cpu OK

So the request is the fix. PYTHON_SKIP names the releases that cannot run the
stack and _python_request turns a bare 3.13 into the range; a venv left on a
skipped interpreter by an earlier run is recreated, on any platform, which the
previous check could not do because it was gated on macOS arm64.

UV_MIN_VERSION also moves to 0.9.3, the first uv whose bundled manifest carries
3.13.9. That is belt-and-braces rather than the fix, since the range resolves on
0.9.2 too. Raising it pulls every 0.8.16-0.9.2 host into the refresh block, so
an existing uv in that range is no longer fatal when the network is unreachable.

Windows reaches such an interpreter differently: uv is handed a resolved path,
never a version, so it cannot pick the patch, but Find-CompatiblePython matches
on the minor version and would return an already-installed 3.13.8.
Remove-SkippedPython turns that into "not found" so the caller installs
$PythonFallbackFullVersion (3.13.13). The uv floor is left alone there, since
the uv-managed Python path is not taken on Windows.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Screen the skipped patch inside the resolver, and never delete the only venv

Windows: Find-CompatiblePython matched on the minor, so the screen sat on
its result and every other caller of the resolver -- the two install
helpers among them -- could still be handed the interpreter the first
call had just rejected. Nulling the result also ended the search, so a
host with 3.13.8 and a healthy 3.12 failed instead of using the 3.12. The
patch is already in the string the minor comes from, so screening during
enumeration costs no extra subprocess and keeps the fallback ladder.

install.sh: the legacy-layout migration moves the old environment into
$VENV_DIR without arming the rollback, so a plain rm -rf before a
recreate that then fails leaves the machine with nothing. Move it aside
through the existing rollback machinery instead.

Ask uv for the series minus the skipped patches rather than for a floor
above them: an offline host, or a uv whose manifest predates 3.13.9, can
still have a good cached 3.13.7 that a floor would refuse. Measured with
uv 0.10.7, only 3.13.7 and 3.13.8 installed, --offline: "3.13" gives
3.13.8, ">=3.13.9,<3.14" errors, ">=3.13,<3.14,!=3.13.8" gives 3.13.7.

Hoist the install.ps1 extractions out of the f-strings: a backslash in an
f-string expression is a syntax error before 3.12 and the repo is 3.9+.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Run the resolver driver only where its fake launcher can execute

The launcher is a /bin/sh script, and Windows has neither a shebang nor a
PATHEXT entry for an extensionless file, so Get-Command never finds it and
Find-CompatiblePython reports "none" whatever versions the tree holds.
Two cases failed on a real windows-latest runner and the third passed for
that reason rather than on merit. Skip the three on Windows, where the
rest of the file still covers the screen, and pair the negative case with
a positive control so a harness that cannot run the launcher fails
instead of quietly agreeing.

* Do not screen the interpreter for an install that never imports torch

Every entry in the skip list is there for one reason: it cannot import
torch. A --no-torch/-NoTorch install never does, so refusing the machine's
only 3.13 would send a locked-down GGUF-only host into a download it may
not be able to complete, over a package it will not install.

Also turn away anything that is not a plain X.Y before the arithmetic:
a relative --python path like 3.13/bin/python survived the globs, and
dash aborts the whole install with "Illegal number" rather than reaching
uv. And keep the uv version probe alive on an image with no awk, which is
precisely the host the offline exception around it exists to protect --
the pipeline exits 127 there and set -e was killing the install before
the code could treat the version as unreadable.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-08-05 03:03:39 -07:00