Skip to content

Commit 959f8c4

Browse files
committed
modify how we download debugpy from pip
1 parent 1b6ce83 commit 959f8c4

File tree

3 files changed

+71
-89
lines changed

3 files changed

+71
-89
lines changed

build/azure-devdiv-pipeline.pre-release.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ extends:
8282

8383
- script: python -m nox --session install_bundled_libs
8484
displayName: Install Python dependencies
85+
env:
86+
USE_PIP_DOWNLOAD: 1
8587

8688
- script: python ./build/update_ext_version.py --for-publishing
8789
displayName: Update build number

build/azure-devdiv-pipeline.stable.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ extends:
7575

7676
- script: python -m nox --session install_bundled_libs
7777
displayName: Install Python dependencies
78+
env:
79+
USE_PIP_DOWNLOAD: 1
7880

7981
- script: python ./build/update_ext_version.py --release --for-publishing
8082
displayName: Update build number

noxfile.py

Lines changed: 67 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import json
88
import os
99
import pathlib
10-
import re
1110
import tempfile
1211
import urllib.request as url_lib
1312
import zipfile
@@ -60,117 +59,96 @@ def install_bundled_libs(session):
6059
)
6160
session.install("packaging")
6261

62+
debugpy_info_json_path = pathlib.Path(__file__).parent / "debugpy_info.json"
63+
debugpy_info = json.loads(debugpy_info_json_path.read_text(encoding="utf-8"))
64+
6365
target = os.environ.get("VSCETARGET", "")
6466
print("target:", target)
65-
download_debugpy_via_pip(session, target)
66-
67-
68-
def _infer_debugpy_version() -> str:
69-
"""Best-effort debugpy version selection.
70-
71-
Priority:
72-
1) DEBUGPY_VERSION env var
73-
2) Extract from debugpy_info.json (if present)
74-
"""
75-
76-
env_version = os.environ.get("DEBUGPY_VERSION")
77-
if env_version:
78-
return env_version
67+
if "darwin" in target:
68+
wheels = debugpy_info["macOS"]
69+
elif "win32-ia32" == target:
70+
wheels = debugpy_info.get("win32", debugpy_info["any"])
71+
elif "win32-x64" == target:
72+
wheels = debugpy_info["win64"]
73+
elif "linux-x64" == target:
74+
wheels = debugpy_info["linux"]
75+
else:
76+
wheels = debugpy_info["any"]
7977

80-
debugpy_info_json_path = pathlib.Path(__file__).parent / "debugpy_info.json"
81-
if not debugpy_info_json_path.exists():
82-
raise FileNotFoundError(
83-
"Missing debugpy version source. Set DEBUGPY_VERSION or add debugpy_info.json."
84-
)
78+
# Use pip download when USE_PIP_DOWNLOAD is set (e.g., for Azure Artifacts feed)
79+
if os.environ.get("USE_PIP_DOWNLOAD"):
80+
download_debugpy_via_pip(session, wheels)
81+
else:
82+
download_url(wheels)
8583

86-
debugpy_info = json.loads(debugpy_info_json_path.read_text(encoding="utf-8"))
87-
for platform_entries in debugpy_info.values():
88-
for entry in platform_entries:
89-
match = re.search(r"/debugpy-([^/]+?)-", entry.get("url", ""))
90-
if match:
91-
return match.group(1)
92-
93-
raise ValueError(
94-
"Could not infer debugpy version from debugpy_info.json. Set DEBUGPY_VERSION."
95-
)
9684

85+
def _parse_wheel_info(url: str) -> dict:
86+
"""Parse version and platform info from a wheel URL.
9787
98-
def download_debugpy_via_pip(session: nox.Session, target: str) -> None:
88+
Example URL: .../debugpy-1.8.19-cp311-cp311-win_amd64.whl
89+
Returns: {"version": "1.8.19", "py_ver": "311", "abi": "cp311", "platform": "win_amd64"}
90+
"""
91+
import re
92+
93+
filename = url.rsplit("/", 1)[-1]
94+
# Wheel filename format: {name}-{version}-{python}-{abi}-{platform}.whl
95+
match = re.match(r"debugpy-([^-]+)-cp(\d+)-([^-]+)-(.+)\.whl", filename)
96+
if match:
97+
return {
98+
"version": match.group(1),
99+
"py_ver": match.group(2),
100+
"abi": match.group(3),
101+
"platform": match.group(4),
102+
}
103+
# Fallback for py2.py3-none-any wheels
104+
match = re.match(r"debugpy-([^-]+)-py\d\.py\d-none-any\.whl", filename)
105+
if match:
106+
return {"version": match.group(1), "py_ver": None, "abi": "none", "platform": "any"}
107+
raise ValueError(f"Could not parse wheel filename: {filename}")
108+
109+
110+
def download_debugpy_via_pip(session: nox.Session, wheels: list) -> None:
99111
"""Downloads debugpy wheels via pip and extracts them into bundled/libs.
100112
101-
This respects pip configuration (index URLs, proxies, certs) and avoids hard-coded
102-
direct downloads from files.pythonhosted.org.
113+
Uses pip to download by package name, allowing pip to use configured
114+
index URLs (e.g., Azure Artifacts feed) instead of direct PyPI URLs.
103115
"""
104-
105-
debugpy_version = _infer_debugpy_version()
106116
libs_dir = pathlib.Path.cwd() / "bundled" / "libs"
107117
libs_dir.mkdir(parents=True, exist_ok=True)
108118

109-
# Match prior behavior: bundle debugpy wheels for the target (or universal fallback).
110-
# We download multiple wheels for multiple CPython versions, because the extension may
111-
# be used with different interpreter versions.
112-
#
113-
# Format: (python_version, implementation, abi, platform)
114-
if "darwin" in target:
115-
wheel_requests = [
116-
("310", "cp", "cp310", "macosx_15_0_x86_64"),
117-
("311", "cp", "cp311", "macosx_15_0_universal2"),
118-
("312", "cp", "cp312", "macosx_15_0_universal2"),
119-
]
120-
elif target == "win32-ia32":
121-
wheel_requests = [
122-
("310", "cp", "cp310", "win32"),
123-
("311", "cp", "cp311", "win32"),
124-
("312", "cp", "cp312", "win32"),
125-
]
126-
elif target == "win32-x64":
127-
wheel_requests = [
128-
("310", "cp", "cp310", "win_amd64"),
129-
("311", "cp", "cp311", "win_amd64"),
130-
("312", "cp", "cp312", "win_amd64"),
131-
]
132-
elif target == "linux-x64":
133-
wheel_requests = [
134-
("310", "cp", "cp310", "manylinux_2_34_x86_64"),
135-
("311", "cp", "cp311", "manylinux_2_34_x86_64"),
136-
("312", "cp", "cp312", "manylinux_2_34_x86_64"),
137-
]
138-
else:
139-
# Universal fallback wheel (py2.py3-none-any).
140-
wheel_requests = [("39", "cp", "none", "any")]
119+
# Parse version and platform info from wheel URLs
120+
parsed = [_parse_wheel_info(w["url"]) for w in wheels]
121+
version = parsed[0]["version"]
141122

142123
with tempfile.TemporaryDirectory(prefix="debugpy_wheels_") as tmp_dir:
143124
tmp_path = pathlib.Path(tmp_dir)
144-
for py_ver, impl, abi, platform_tag in wheel_requests:
145-
session.run(
146-
"python",
147-
"-m",
148-
"pip",
149-
"download",
150-
f"debugpy=={debugpy_version}",
125+
126+
for info in parsed:
127+
args = [
128+
"python", "-m", "pip", "download",
129+
f"debugpy=={version}",
151130
"--no-deps",
152-
"--only-binary",
153-
":all:",
154-
"--dest",
155-
str(tmp_path),
156-
"--python-version",
157-
py_ver,
158-
"--implementation",
159-
impl,
160-
"--abi",
161-
abi,
162-
"--platform",
163-
platform_tag,
164-
)
131+
"--only-binary", ":all:",
132+
"--dest", str(tmp_path),
133+
]
134+
if info["py_ver"]:
135+
# Platform-specific wheel
136+
args.extend(["--python-version", info["py_ver"]])
137+
args.extend(["--implementation", "cp"])
138+
args.extend(["--abi", info["abi"]])
139+
args.extend(["--platform", info["platform"]])
140+
# For none-any wheels, no platform args needed
141+
142+
session.run(*args)
165143

166144
wheel_paths = sorted(tmp_path.glob("debugpy-*.whl"))
167145
if not wheel_paths:
168146
raise FileNotFoundError(
169-
f"pip download produced no debugpy wheels for version {debugpy_version}."
147+
f"pip download produced no debugpy wheels for version {version}."
170148
)
171149

172150
for wheel_path in wheel_paths:
173-
print("Download:", wheel_path.name)
151+
print("Downloaded:", wheel_path.name)
174152
with zipfile.ZipFile(wheel_path, "r") as wheel:
175153
for zip_info in wheel.infolist():
176154
print("\t" + zip_info.filename)

0 commit comments

Comments
 (0)