1919# verify_install A # run a single check
2020# verify_install A C E # run a subset
2121# verify_install --version 2026.4.5.2 # pin a specific PyPI version (A/C/D)
22+ # verify_install --testpypi # install from test.pypi.org (pre-release rehearsal)
2223# verify_install --keep # don't clean up at the end
2324# verify_install -h | --help
2425
@@ -40,7 +41,7 @@ usage() {
4041verify_install — release-readiness gate for PyAutoLens.
4142
4243Usage:
43- verify_install [CHECKS...] [--version VERSION] [--keep] [-h]
44+ verify_install [CHECKS...] [--version VERSION] [--testpypi] [-- keep] [-h]
4445
4546Checks:
4647 A pip install autolens (default python3) + start_here.py + welcome.py
@@ -53,6 +54,9 @@ Default: run all checks.
5354
5455Options:
5556 --version VERSION Pin a specific PyPI version (applies to A, C, D).
57+ --testpypi Install from test.pypi.org with PyPI as a fallback for
58+ non-PyAuto deps (applies to A, C, D, E). Use this for a
59+ pre-release rehearsal against a TestPyPI dry-run upload.
5660 --keep Don't clean up venvs / conda envs / clones at the end.
5761 -h, --help Show this help.
5862USAGE
6266
6367TARGET_VERSION=" "
6468KEEP=0
69+ USE_TESTPYPI=0
6570REQUESTED_CHECKS=()
6671
6772while [ $# -gt 0 ]; do
@@ -78,6 +83,10 @@ while [ $# -gt 0 ]; do
7883 TARGET_VERSION=" $2 "
7984 shift 2
8085 ;;
86+ --testpypi)
87+ USE_TESTPYPI=1
88+ shift
89+ ;;
8190 --keep)
8291 KEEP=1
8392 shift
@@ -94,6 +103,18 @@ while [ $# -gt 0 ]; do
94103 esac
95104done
96105
106+ # When --testpypi is set, route every PyAuto-package pip install through
107+ # TestPyPI as the primary index and fall back to PyPI for transitive deps not
108+ # mirrored there (matplotlib, scipy, nufftax, jax, etc.). Cleared otherwise —
109+ # keeps PyPI as the sole source for the default release-gate path.
110+ #
111+ # Stored as an array so the two flags are passed cleanly without word-split
112+ # surprises at every `pip install` site.
113+ PIP_INDEX_ARGS=()
114+ if [ " $USE_TESTPYPI " -eq 1 ]; then
115+ PIP_INDEX_ARGS=(--index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/)
116+ fi
117+
97118if [ ${# REQUESTED_CHECKS[@]} -eq 0 ]; then
98119 REQUESTED_CHECKS=(all)
99120fi
@@ -169,15 +190,15 @@ check_a() {
169190 pip install --upgrade pip
170191
171192 step " pip install $PIP_INSTALL_TARGET "
172- if ! pip install " $PIP_INSTALL_TARGET " | & tee /tmp/A_pip.log; then
193+ if ! pip install " ${PIP_INDEX_ARGS[@]} " " $ PIP_INSTALL_TARGET" | & tee /tmp/A_pip.log; then
173194 RESULTS+=(" A|FAIL|pip install $PIP_INSTALL_TARGET failed" )
174195 tail_log " Check A pip output" " $( cat /tmp/A_pip.log 2> /dev/null) "
175196 deactivate
176197 return
177198 fi
178199
179200 step " pip install numba"
180- pip install numba | & tee /tmp/A_numba.log
201+ pip install " ${PIP_INDEX_ARGS[@]} " numba | & tee /tmp/A_numba.log
181202
182203 step " showing installed versions"
183204 python -c "
@@ -252,7 +273,7 @@ check_b_one() {
252273
253274 step " $pybin : pip install $PIP_INSTALL_TARGET "
254275 local pip_out pip_rc=0
255- pip_out=$( pip install " $PIP_INSTALL_TARGET " 2>&1 ) || pip_rc=$?
276+ pip_out=$( pip install " ${PIP_INDEX_ARGS[@]} " " $ PIP_INSTALL_TARGET" 2>&1 ) || pip_rc=$?
256277
257278 if [ " $pip_rc " -ne 0 ]; then
258279 RESULTS+=(" B|FAIL|$pybin pip install failed (rc=$pip_rc )" )
@@ -330,15 +351,16 @@ check_c() {
330351 conda run -n " $env_name " pip install --upgrade pip
331352
332353 step " conda pip install $PIP_INSTALL_TARGET --no-cache-dir"
333- if ! conda run -n " $env_name " pip install " $PIP_INSTALL_TARGET " --no-cache-dir \
334- | & tee /tmp/C_pip.log; then
354+ if ! conda run -n " $env_name " pip install " ${PIP_INDEX_ARGS[@]} " \
355+ " $PIP_INSTALL_TARGET " --no-cache-dir | & tee /tmp/C_pip.log; then
335356 RESULTS+=(" C|FAIL|conda pip install $PIP_INSTALL_TARGET failed" )
336357 tail_log " Check C pip output" " $( cat /tmp/C_pip.log 2> /dev/null) "
337358 return
338359 fi
339360
340361 step " conda pip install numba --no-cache-dir"
341- conda run -n " $env_name " pip install numba --no-cache-dir | & tee /tmp/C_numba.log
362+ conda run -n " $env_name " pip install " ${PIP_INDEX_ARGS[@]} " \
363+ numba --no-cache-dir | & tee /tmp/C_numba.log
342364
343365 step " cloning autolens_workspace"
344366 if ! git clone --depth 1 \
@@ -387,7 +409,7 @@ check_d() {
387409 pip install --upgrade pip > /dev/null 2>&1
388410
389411 step " pip install $PIP_INSTALL_OPTIONAL "
390- pip install " $PIP_INSTALL_OPTIONAL " | & tee /tmp/D_pip.log
412+ pip install " ${PIP_INDEX_ARGS[@]} " " $ PIP_INSTALL_OPTIONAL" | & tee /tmp/D_pip.log
391413 local pip_rc=${PIPESTATUS[0]}
392414
393415 step " import autolens"
@@ -428,7 +450,7 @@ check_e() {
428450 # symbol in autogalaxy 2026.5.1.4). Same multi-pin pattern that release.yml
429451 # uses (lines 130-138).
430452 step " pip install autoconf/autoarray/autofit/autogalaxy/autolens==2026.2.26.4"
431- pip install \
453+ pip install " ${PIP_INDEX_ARGS[@]} " \
432454 autoconf==2026.2.26.4 \
433455 autoarray==2026.2.26.4 \
434456 autofit==2026.2.26.4 \
0 commit comments