Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions azure-pipelines/pipelines.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ stages:
vmImage: ubuntu-latest

variables:
python.version: "3.9"
python.version: "3.10"

steps:

Expand Down Expand Up @@ -125,8 +125,6 @@ stages:

strategy:
matrix:
py39:
python.version: 3.9
py310:
python.version: 3.10
py311:
Expand Down Expand Up @@ -170,8 +168,6 @@ stages:

strategy:
matrix:
py39:
python.version: 3.9
py310:
python.version: 3.10
py311:
Expand Down Expand Up @@ -215,11 +211,6 @@ stages:

strategy:
matrix:
py39:
python.version: 3.9
py39_32:
python.version: 3.9
architecture: x86
py310:
python.version: 3.10
py311:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📍 azure-pipelines/pipelines.yaml:211
This revision removes py39 and py39_32 and adds nothing in their place, so the Windows matrix is now py310py314 with zero 32-bit legs — yet setup.py:is_applicable still packages win32 artifacts (return plat in ("win32", "win-amd64")). debugpy continues to ship a win32 wheel surface with no x86 CI signal. Either restore a single py310_32 (architecture: x86) leg — and smoke-install tests/requirements.txt on win32 cp310 to confirm the unpinned C-extension deps resolve — or remove win32 from setup.py:is_applicable so packaging and CI agree. Do not merge with a shipped-but-untested architecture.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — this is a real tension, but I don't think either literal option is the right change to make inside this PR, so I'm flagging it for a maintainer call rather than forcing it here. Reasoning, with evidence:

Option A — restore a py310_32 (x86) leg: This re-introduces the exact failure class this PR exists to remove. As established in the (now-resolved) thread above, gevent ships no cp310-win32 wheel (only ...-cp310-cp310-win_amd64.whl), so pip install -r tests/requirements.txt on win32 cp310 falls back to a source build of gevent (greenlet/libev/c-ares) and risks failing the leg at install. There's no PEP 508 marker that reliably distinguishes a 32-bit interpreter on 64-bit Windows (platform_machine reflects the OS, not the interpreter), so gevent can't be cleanly gated off only the x86 leg without either still source-building or silently dropping gevent coverage. Adding the leg back is therefore a coverage/risk tradeoff that you flagged yourself — a maintainer decision, not something I should force in autonomously.

Option B — remove win32 from setup.py:is_applicable: This doesn't actually stop debugpy from shipping a win32 wheel — is_applicable only filters which vendored pydevd native binaries (.exe/.dll/.pdb/.pyd) get copied into the wheel. Dropping win32 there would still build a win32 wheel, just a broken one missing the attach-to-process binaries. Genuinely retiring the win32 wheel surface means changing the build/packaging matrix and would break existing 32-bit Windows users — clearly out of scope for "drop EOL 3.9/3.8 + pin secure dep floors."

Note this PR didn't newly create the gap: the only prior 32-bit leg was py39_32, removed here solely because Python 3.9 is EOL. The win32 packaging surface is unchanged.

My recommendation: keep win32 packaging as-is in this PR and track "restore an x86 test signal (wheel-only deps, gevent excluded on x86)" or "retire the win32 wheel" as a separate, deliberate follow-up. Happy to implement whichever direction you choose — leaving this thread open for your call.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This revision removes both py39 and py39_32 — the base branch's only architecture: x86 leg — leaving the Windows matrix at py310py314 under the global architecture: x64. Meanwhile setup.py (is_applicable) still ships win32 wheels (plat in ("win32", "win-amd64")), so debugpy continues to package an x86 surface with zero x86 CI signal: a win32-only regression in the attach binaries could ship undetected. Consider either restoring one py310 architecture: x86 leg (at minimum smoke-installing tests/requirements.txt on win32 cp310), or narrowing setup.py:is_applicable to drop win32 so packaging and CI coverage agree.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — this is the same x86-CI vs. win32-packaging tension raised (and discussed in depth) in the thread above, so I'll consolidate here and keep it open for a maintainer call rather than force a change in this PR.

Both options you list have been evaluated, with evidence:

  • Restore a py310 x86 leg. I actually tried this in this PR (804b4639 "ci: restore x86 Windows leg on Python 3.10") and had to revert it (d2c3ac40 "ci: drop x86 Windows leg (gevent has no cp310-win32 wheel)"). gevent publishes no cp310-win32 wheel, so pip install -r tests/requirements.txt on win32 cp310 falls back to a source build (greenlet/libev/c-ares) and risks failing the leg at install — the exact failure class this PR exists to remove. There's also no PEP 508 marker that reliably distinguishes a 32-bit interpreter on 64-bit Windows (platform_machine reflects the OS, not the interpreter), so gevent can't be cleanly excluded on just the x86 leg.

  • Drop win32 from setup.py:is_applicable. is_applicable only filters which vendored pydevd native binaries get copied into the wheel; it does not stop a win32 wheel from being built. Removing win32 there would still ship a win32 wheel — just a broken one missing the attach-to-process binaries. Genuinely retiring the win32 wheel surface is a packaging-matrix change that would break existing 32-bit users, which is out of scope for "drop EOL 3.9/3.8 + pin secure dep floors."

For context, this PR didn't create the gap: the only prior x86 leg was py39_32, removed here solely because Python 3.9 is EOL; the win32 packaging surface is unchanged.

Recommendation: keep win32 packaging as-is in this PR (which you've approved) and track "restore an x86 test signal with wheel-only deps (gevent excluded on x86)" or "retire the win32 wheel surface" as a separate, deliberate follow-up. Happy to implement whichever direction you choose — leaving this open for your call.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — this is the same x86-CI vs. win32-packaging tension raised (and discussed in depth) in the thread above, so I'll consolidate here and keep it open for a maintainer call rather than force a change in this PR.

Both options you list have been evaluated, with evidence:

  • Restore a py310 x86 leg. I actually tried this in this PR (804b4639 "ci: restore x86 Windows leg on Python 3.10") and had to revert it (d2c3ac40 "ci: drop x86 Windows leg (gevent has no cp310-win32 wheel)"). gevent publishes no cp310-win32 wheel, so pip install -r tests/requirements.txt on win32 cp310 falls back to a source build (greenlet/libev/c-ares) and risks failing the leg at install — the exact failure class this PR exists to remove. There's also no PEP 508 marker that reliably distinguishes a 32-bit interpreter on 64-bit Windows (platform_machine reflects the OS, not the interpreter), so gevent can't be cleanly excluded on just the x86 leg.

  • Drop win32 from setup.py:is_applicable. is_applicable only filters which vendored pydevd native binaries get copied into the wheel; it does not stop a win32 wheel from being built. Removing win32 there would still ship a win32 wheel — just a broken one missing the attach-to-process binaries. Genuinely retiring the win32 wheel surface is a packaging-matrix change that would break existing 32-bit users, which is out of scope for "drop EOL 3.9/3.8 + pin secure dep floors."

For context, this PR didn't create the gap: the only prior x86 leg was py39_32, removed here solely because Python 3.9 is EOL; the win32 packaging surface is unchanged.

Recommendation: keep win32 packaging as-is in this PR (which you've approved) and track "restore an x86 test signal with wheel-only deps (gevent excluded on x86)" or "retire the win32 wheel surface" as a separate, deliberate follow-up. Happy to implement whichever direction you choose — leaving this open for your call.

Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ exclude = '''
'''

[tool.pyright]
pythonVersion = "3.8"
pythonVersion = "3.10"
include = ["src/**", "tests/**" ]
extraPaths = ["src/debugpy/_vendored/pydevd", "src/debugpy/_vendored/pydevd/pydevd_attach_to_process"]
ignore = ["src/debugpy/_vendored/pydevd", "src/debugpy/_version.py"]
Expand Down Expand Up @@ -71,8 +71,8 @@ line-length = 88
# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

# Assume Python 3.8
target-version = "py38"
# Assume Python 3.10
target-version = "py310"

[tool.ruff.per-file-ignores]
"tests/debugpy/test_breakpoints.py" = ["F841"]
Expand Down
4 changes: 1 addition & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,9 @@ def tail_is(*suffixes):
project_urls={
"Source": "https://github.com/microsoft/debugpy",
},
python_requires=">=3.8",
python_requires=">=3.10",
Comment thread
rchiodo marked this conversation as resolved.
classifiers=[
"Development Status :: 5 - Production/Stable",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand Down
7 changes: 5 additions & 2 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Used to run the tests:

pytest
pytest>=9.0.3 # CVE-2025-71176 (vulnerable <= 9.0.2)
pytest-xdist
pytest-cov
pytest-timeout
Comment thread
rchiodo marked this conversation as resolved.
Expand All @@ -18,7 +18,10 @@ django
flask
gevent
numpy
requests
requests>=2.33.0 # CVE-2026-25645 (vulnerable < 2.33.0)
# urllib3 is pulled in transitively by requests; pin a secure floor for
# CVE-2026-44431 and CVE-2026-44432 (vulnerable 2.6.0 <= x < 2.7.0).
urllib3>=2.7.0
typing_extensions

# Used to build pydevd attach to process binaries:
Expand Down
4 changes: 1 addition & 3 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py{38,39,310,311,312,313,314}{,-cov}
envlist = py{310,311,312,313,314}{,-cov}

[testenv]
deps = -rtests/requirements.txt
Expand All @@ -8,7 +8,5 @@ setenv =
DEBUGPY_TEST=1
commands_pre = python build_attach_binaries.py
commands =
py{38,39}-!cov: python -m pytest {posargs}
py{38,39}-cov: python -m pytest --cov --cov-append --cov-config=.coveragerc {posargs}
py{310,311,312,313,314}-!cov: python -Xfrozen_modules=off -m pytest {posargs}
py{310,311,312,313,314}-cov: python -Xfrozen_modules=off -m pytest --cov --cov-append --cov-config=.coveragerc {posargs}
Loading