Skip to content

Commit

Permalink
Fix bootstrap install script on windows (astral-sh#1162)
Browse files Browse the repository at this point in the history
Windows doesn't support symlinks, doesn't use a `bin` directory and all
pythons are called `python.exe`.

Note that this is still broken, `.\bin\python3.10.13` is missing its
.exe extension and renaming it to `.\bin\python3.10.13.exe` makes it
complain about not finding python310.dll.
  • Loading branch information
konstin authored Feb 3, 2024
1 parent bc2f8f5 commit 0199ad6
Showing 1 changed file with 22 additions and 10 deletions.
32 changes: 22 additions & 10 deletions scripts/bootstrap/install.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "zstandard==0.22.0",
# ]
# ///
#
# Download required Python versions and install to `bin`
# Uses prebuilt Python distributions from indygreg/python-build-standalone
Expand All @@ -13,6 +19,10 @@
#
# python scripts/bootstrap/install.py
#
# Or
#
# pipx run scripts/bootstrap/install.py
#
# The Python versions are installed from `.python_versions`.
# Python versions are linked in-order such that the _last_ defined version will be the default.
#
Expand Down Expand Up @@ -96,8 +106,8 @@ def sha256_file(path: Path):
print(f"No matching download for {key}")
sys.exit(1)

filename = url.split("/")[-1]
if not install_dir.exists():
filename = url.split("/")[-1]
print(f"Downloading {urllib.parse.unquote(filename)}")
download_path = THIS_DIR / filename
with urllib.request.urlopen(url) as response:
Expand Down Expand Up @@ -129,28 +139,30 @@ def sha256_file(path: Path):
already_exists = True
print("Already available, skipping download")

# Use relative paths for links so if the bin is moved they don't break
executable = "." / install_dir.relative_to(BIN_DIR) / "install" / "bin" / "python3"
if PLATFORM == "win32":
executable = executable.with_suffix(".exe")
executable = install_dir / "install" / "python.exe"
else:
# Use relative paths for links so if the bin is moved they don't break
executable = "." / install_dir.relative_to(BIN_DIR) / "install" / "bin" / "python3"

major = versions_metadata[key]["major"]
minor = versions_metadata[key]["minor"]

# Link as all version tuples, later versions in the file will take precedence
BIN_DIR.mkdir(parents=True, exist_ok=True)
targets = (

targets = [
(BIN_DIR / f"python{version}"),
(BIN_DIR / f"python{major}.{minor}"),
(BIN_DIR / f"python{major}"),
(BIN_DIR / "python"),
)
]
for target in targets:
if PLATFORM == "win32":
target = target.with_suffix(".exe")

target.unlink(missing_ok=True)
target.symlink_to(executable)
if PLATFORM == "win32":
target.hardlink_to(executable)
else:
target.symlink_to(executable)

if already_exists:
print(f"Updated executables for python{version}")
Expand Down

0 comments on commit 0199ad6

Please sign in to comment.