feat(local-dev): pick a usable Python and offer to install a missing toolchain - #7073
Closed
Yicong-Huang wants to merge 1 commit into
Closed
feat(local-dev): pick a usable Python and offer to install a missing toolchain#7073Yicong-Huang wants to merge 1 commit into
Yicong-Huang wants to merge 1 commit into
Conversation
Contributor
Automated Reviewer SuggestionsBased on the
|
Yicong-Huang
force-pushed
the
fix/local-dev-linux
branch
from
July 29, 2026 22:44
4e2fcdf to
347c887
Compare
Yicong-Huang
force-pushed
the
feat/local-dev-toolchain-install
branch
from
July 29, 2026 22:45
99a3e30 to
78e091f
Compare
…toolchain
Two halves of the same fresh-machine problem.
**The interpreter that runs Python UDFs was picked blindly.**
`UDF_PYTHON_PATH` defaulted to `command -v python3` at source time — the system
interpreter, which almost never has `amber/requirements.txt` installed. Python
UDFs then failed at worker launch on a stack of import errors that pointed
nowhere near the interpreter choice, and the venv AGENTS.md tells contributors
to create (`<workspace>/venv312`) was ignored, as was an already-activated
`$VIRTUAL_ENV`.
Now resolved lazily, taking the first candidate that is Python 3.12 *and* can
import the worker's deps:
$UDF_PYTHON_PATH -> $VIRTUAL_ENV -> <workspace>/venv312 -> pyenv 3.12
-> python3.12 on PATH -> python3 on PATH
The chosen interpreter is reported the way the JDK probe reports JAVA_HOME. An
explicit `UDF_PYTHON_PATH` still wins — it's the documented override — but now
says so when it can't import what a worker needs. "No 3.12 anywhere" and "3.12
without amber's deps" are reported differently, because they need different
fixes and the old default silently produced the second one. Resolution is lazy
so `status` / `logs` / `--help` don't spawn an interpreter per candidate, and
never fatal: the JVM services run fine without a Python toolchain.
**A missing tool was described, never offered.** `_install_hint` printed a
suggestion and gave up, so a fresh machine meant hand-installing several things
and re-running `up` after each one to find the next gap. A missing JDK 17, Node
or Python 3.12 is now offered for install after showing the exact command:
the distro package manager for the JDK (SDKMAN when there is none), nvm for
Node, pyenv for Python — both bootstrapping themselves if absent.
The decision helpers (`_pkg_manager`, `_install_cmd_for`) only ever print what
would run; a separate step executes it. That keeps the choice unit-testable
without installing anything, and means the user is shown the command — `sudo`
included — before being asked.
Deliberately unchanged for non-interactive callers: without a TTY nothing is
ever prompted and the old print-a-hint-and-fail behaviour stands, so scripted
and CI runs can't hang on a read. `--install-missing` answers yes without
asking, `--no-install` only ever prints; the contradiction is refused rather
than silently resolved. docker and sbt stay hint-only — docker needs a daemon,
group membership and a re-login, which isn't something to do behind a y/n
prompt.
Closes #7066
Yicong-Huang
force-pushed
the
fix/local-dev-linux
branch
from
July 29, 2026 22:53
347c887 to
b68bfe3
Compare
Yicong-Huang
force-pushed
the
feat/local-dev-toolchain-install
branch
from
July 29, 2026 22:53
78e091f to
6025b63
Compare
Contributor
Author
|
Superseded by #7078 — same commits, but opened from a fork branch as it should have been. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes were proposed in this PR?
Two halves of the same fresh-machine problem.
The interpreter that runs Python UDFs was picked blindly.
UDF_PYTHON_PATHdefaulted tocommand -v python3at source time — the systeminterpreter, which almost never has
amber/requirements.txtinstalled. PythonUDFs then failed at worker launch on a stack of import errors that pointed
nowhere near the interpreter choice. The venv AGENTS.md tells contributors to
create (
<workspace>/venv312) was ignored, as was an already-activated$VIRTUAL_ENV.Resolution is now lazy, and takes the first candidate that is Python 3.12
and can import what a worker needs:
The choice is reported the way the JDK probe reports
JAVA_HOME. An explicitUDF_PYTHON_PATHstill wins — it is the documented override — but now says sowhen it can't import the deps. "No 3.12 anywhere" and "3.12 without amber's
deps" are reported differently, because they need different fixes and the old
default silently produced the second one. Lazy so
status/logs/--helpdon't spawn an interpreter per candidate, and never fatal: the JVM services run
fine without a Python toolchain, only UDFs don't.
A missing tool was described, never offered.
_install_hintprinted asuggestion and gave up, so a fresh machine meant hand-installing five or six
things, re-running
upafter each to discover the next gap. A missing JDK 17,Node or Python 3.12 is now offered for install, after showing the exact command:
apt-get/dnf/yum/pacman/zypper),brewon macOS, SDKMAN when there is nonenvm(bootstraps nvm first if absent)pyenv(bootstraps pyenv first if absent)jenvis not used: it switches between JDKs, it cannot install one.The decision helpers (
_pkg_manager,_install_cmd_for) only ever printwhat would run; a separate step executes it. That keeps the choice
unit-testable without installing anything, and it means the user sees the
command —
sudoincluded — before being asked.Behaviour deliberately preserved for non-interactive callers: without a TTY
nothing is ever prompted and the old print-a-hint-and-fail path stands, so
scripted and CI runs cannot hang on a
read.--install-missinganswers yeswithout asking,
--no-installonly ever prints the hint, and the contradictionis refused rather than silently resolved. docker and sbt stay hint-only —
docker needs a daemon, group membership and a re-login, which is not something
to do behind a y/n prompt.
Any related issues, documentation, discussions?
Closes #7066
Stacked on #7070 (#7065).
How was this PR tested?
New coverage in the existing
infra-job suite. Everything goes through thepure decision helpers, so CI asserts on what would be installed without
installing anything; the Python probes are driven by fake interpreters that
echo a version or set an exit code:
test_is_dirty_after_seed_then_editis pre-existing and unrelated — itreproduces identically on a pristine
upstream/maincheckout on this machine,and this PR touches neither
tui.pynor that test. Filed separately.Manually, on Ubuntu 24.04.4 with the amber deps installed into a sibling
venv312and nothing inUDF_PYTHON_PATH— it finds the venv rather than thesystem interpreter the old default would have taken:
The consent path, forced by pinning a version that cannot exist
(
TEXERA_PYTHON_VERSION=3.99). With a TTY it shows the command and asks; theanswer here was
n, and the run continued:Without a TTY (
</dev/null) the same run prints the warning, never prompts,does not hang, and exits 0. Both flags are accepted on their own
(
auto --no-install,auto --install-missing→ rc 0) and rejected together(rc 2).
Not exercised end-to-end: actually running the JDK / Node / pyenv installers,
since this machine already has all three. The commands themselves are asserted
by the tests above; the execution step is a
bash -lcof exactly the stringshown to the user.
Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Opus 5)