From a5364fd76d5f9d062ac94781ee570ecaa5db2b3b Mon Sep 17 00:00:00 2001 From: Marcus Caisey Date: Wed, 1 Apr 2026 10:34:32 +0100 Subject: [PATCH 1/4] Include debugpy in debug pex when configured as debugger --- third_party/python/BUILD | 7 +++++-- tools/please_pex/BUILD | 1 + tools/please_pex/pex/pex_main.py | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/third_party/python/BUILD b/third_party/python/BUILD index 35d6105..11249a0 100644 --- a/third_party/python/BUILD +++ b/third_party/python/BUILD @@ -417,9 +417,12 @@ pip_library( python_wheel( name = "debugpy", - hashes = ["f058c204341fd7ff800ee0edafc106ca0fb1c9857e8a8895a6e04cca3ddcb7bf"], + hashes = ["5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7"], licences = ["MIT"], - version = "1.5.0", + version = "1.8.20", + zip_safe = False, + # There doesn't seem to be a predictable URL for this version of debugpy so we need to resolve it instead. + tool = "//tools/wheel_resolver", ) python_wheel( diff --git a/tools/please_pex/BUILD b/tools/please_pex/BUILD index 1483108..02c3642 100644 --- a/tools/please_pex/BUILD +++ b/tools/please_pex/BUILD @@ -44,6 +44,7 @@ genrule( visibility = ["PUBLIC"], deps = [ "//third_party/python:behave_bootstrap", + "//third_party/python:debugpy", "//third_party/python:pytest_bootstrap", "//third_party/python:unittest_bootstrap", ], diff --git a/tools/please_pex/pex/pex_main.py b/tools/please_pex/pex/pex_main.py index 374d5c3..76a8fc2 100644 --- a/tools/please_pex/pex/pex_main.py +++ b/tools/please_pex/pex/pex_main.py @@ -92,6 +92,7 @@ def _explode_zip(): # that the cache has already been prepared. lockfile.write("pex unzip completed") sys.path = [PEX_PATH] + [x for x in sys.path if x != PEX] + sys.path.insert(1, os.path.join(sys.path[0], '.bootstrap')) try: yield finally: From c55124f454d72b7d9bd5c61bedfbe2397ffed3a7 Mon Sep 17 00:00:00 2001 From: Marcus Caisey Date: Fri, 3 Apr 2026 10:34:02 +0100 Subject: [PATCH 2/4] Resolve //third_party/python:debugpy dep cycle --- third_party/python/BUILD | 2 +- tools/BUILD | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/third_party/python/BUILD b/third_party/python/BUILD index 11249a0..2dd8db7 100644 --- a/third_party/python/BUILD +++ b/third_party/python/BUILD @@ -422,7 +422,7 @@ python_wheel( version = "1.8.20", zip_safe = False, # There doesn't seem to be a predictable URL for this version of debugpy so we need to resolve it instead. - tool = "//tools/wheel_resolver", + tool = "//tools:wheel_resolver", ) python_wheel( diff --git a/tools/BUILD b/tools/BUILD index 8cf9d22..3e70160 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -13,3 +13,20 @@ remote_file( binary = True, visibility = ["PUBLIC"], ) + +_WHEEL_RESOLVER_VERSION = "2.0.0" + +remote_file( + name = "wheel_resolver", + url = + f"https://github.com/please-build/python-rules/releases/download/wheel_resolver-v{_WHEEL_RESOLVER_VERSION}/wheel_resolver-{_WHEEL_RESOLVER_VERSION}-{CONFIG.OS}_{CONFIG.ARCH}", + hashes = [ + "sha256:b48315ec1c6670faf7feb2a532a4d0cb104a03113525ef1799062d7576f66b36", # darwin_amd64 + "sha256:70db6d2eb18ab915f555824a8f29fe0909bcf87db0b583a5d6ad3156a54a034a", # darwin_arm64 + "sha256:d47802282b4acf1669a1d69531c69eb2dd3f0f069fd8e59d0c9aff946f7aff44", # freebsd_amd64 + "sha256:6aa0304bde5ab5f68d3415fd8761f6684f5c88835791b0dbd12f909120d797c6", # linux_amd64 + "sha256:09e340203aa88d4e9de7f61b044d1f29fb688abf3c8b7547f80ad6ca3e441495", # linux_arm64 + ], + binary = True, + visibility = ["PUBLIC"], +) From 2f4b3f0266292195b1e5837f3737023954eac751 Mon Sep 17 00:00:00 2001 From: Marcus Caisey Date: Fri, 3 Apr 2026 11:49:13 +0100 Subject: [PATCH 3/4] Update CPython FreeBSD ports --- third_party/cc/cpython/BUILD | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/third_party/cc/cpython/BUILD b/third_party/cc/cpython/BUILD index d7ad816..2204e54 100644 --- a/third_party/cc/cpython/BUILD +++ b/third_party/cc/cpython/BUILD @@ -46,16 +46,16 @@ _python_build_standalone_hashes = { } _freebsd_ports_hashes = { - "py310-sqlite3-3.10.19_10": "b5f9ea064158b99f8ba4d07b29f40248ce53dbc1cbe66b8feb5812579d21b0b7", - "py311-sqlite3-3.11.14_10": "4204b1ef19e99fc210063537b04c2e6d4726ca5caaf8a86e19c5a1c3f6bd71de", - "py312-sqlite3-3.12.12_10": "99913911d9344ee9e6295ee94c42bc8249825f8cfa3e763b6a747d2c96ffb4ca", - "py313-sqlite3-3.13.9_10": "51aa38d1f5f0ee44fb193104ffdd4f3f81980151e177f87ea3af428305e222d1", - "py314-sqlite3-3.14.0_10": "8065f6f790cc8b2fb053739772b0cb75aa5baf2db1e0a5d1ce102dcf7b181edf", - "python310-3.10.19": "df2c924f1bf36352139c6c86adef4cca0c5461b1f127ed1cd4a40921402d2a75", - "python311-3.11.14": "af51ac586e722005655402f8d191d3da60a18825b51afb0b482d2f96161ac32e", - "python312-3.12.12_2": "9c307087a16a2d01d94a05c27ed124af66b8c7e0b34b55c4973508f3445f45c7", - "python313-3.13.9": "667931b37d69046191681313fc8283bfca68b1e389bbfc1cfc266a0209134ed3", - "python314-3.14.0_1": "b6e9e69ed6b0ab92ac47f5f9e1a8e9aaec0534041aa738854d14088b17ba2608", + "py310-sqlite3-3.10.20_10": "e1d98c42c304dd2a7b82df472e5f40b7b32bbccd5dc0840777ba512b9c34f0dd", + "py311-sqlite3-3.11.15_10": "b4c650655f3a359b696eeeffa09216372391e77a7ea9b2d20a6bdd03835d523a", + "py312-sqlite3-3.12.13_10": "f0cac45538e97db4568bb53e8bb718baf656030c6ea4ed24878b236e9b3b4a04", + "py313-sqlite3-3.13.12_10": "b271568ca46386389ff4fc71377da22f4d8f7e571b662d255b2ea0ee684e82cf", + "py314-sqlite3-3.14.3_10": "7b6cf7065f063e843e57a17ab70278af755716c9c6cc03c0106306aa5313ad76", + "python310-3.10.20": "e86d42a8272ae6678de0cf9b7a67380480b354c91c9a680906e7d1af5ca48f7a", + "python311-3.11.15": "57f2f222a89b92b7c7d516fc28d5ef16c2e5cb91516ce9ac45f2363543212d46", + "python312-3.12.13": "fe5bada2443d703634e3d09cf69d7fbc1f63fa34bc85c02447258f1c8f6c45bd", + "python313-3.13.12": "4f62b88be3b1fcace75dcaa8ac0c6318f8a4fc37b36f222a9839ac6d3efff176", + "python314-3.14.3": "1d334e711fedf99e819f1ceb14bacb5162c9c9e5eee805623c704e8a7ceaaa5c", } for minor in ["3.10", "3.11", "3.12", "3.13", "3.14"]: @@ -67,13 +67,13 @@ for minor in ["3.10", "3.11", "3.12", "3.13", "3.14"]: python_pkg = remote_file( name = tag(f"cpython_{minor}", "python_pkg"), - url = f"https://pkg.freebsd.org/FreeBSD:14:amd64/latest/All/{python_pkg_name}.pkg", + url = f"https://pkg.freebsd.org/FreeBSD:14:amd64/quarterly/All/{python_pkg_name}.pkg", hashes = [_freebsd_ports_hashes[python_pkg_name]], ) python_sqlite3_pkg = remote_file( name = tag(f"cpython_{minor}", "python_sqlite3_pkg"), - url = f"https://pkg.freebsd.org/FreeBSD:14:amd64/latest/All/{python_sqlite3_pkg_name}.pkg", + url = f"https://pkg.freebsd.org/FreeBSD:14:amd64/quarterly/All/{python_sqlite3_pkg_name}.pkg", hashes = [_freebsd_ports_hashes[python_sqlite3_pkg_name]], ) From 1510fe065d9e835aeadea6a3f63eba5e61b86242 Mon Sep 17 00:00:00 2001 From: Marcus Caisey Date: Fri, 3 Apr 2026 19:32:55 +0100 Subject: [PATCH 4/4] Download pure debugpy wheel --- build_defs/python.build_defs | 9 ++++++++- third_party/python/BUILD | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/build_defs/python.build_defs b/build_defs/python.build_defs index 6076dc6..543b992 100644 --- a/build_defs/python.build_defs +++ b/build_defs/python.build_defs @@ -551,7 +551,7 @@ def python_wheel(name:str, version:str, labels:list=[], hashes:list=None, packag deps:list=[], name_scheme:str|list=CONFIG.PYTHON.WHEEL_NAME_SCHEME, strip:list=['*.pyc', 'tests'], binary = False, entry_points:dict|str={}, tool:str=CONFIG.PYTHON.WHEEL_TOOL, prereleases:bool=CONFIG.PYTHON.PRERELEASES, - tool_verbosity:str=CONFIG.PYTHON.VERBOSITY, interpreter:str=CONFIG.PYTHON.DEFAULT_INTERPRETER, + tool_verbosity:str=CONFIG.PYTHON.VERBOSITY, pure:bool=False, interpreter:str=CONFIG.PYTHON.DEFAULT_INTERPRETER, module_dir:str=CONFIG.PYTHON.MODULE_DIR): """Downloads a Python wheel and extracts it. @@ -599,6 +599,9 @@ def python_wheel(name:str, version:str, labels:list=[], hashes:list=None, packag module_dir (str): The path to the third party python directory in python import path format. Defaults to value of python.moduledir setting. tool (str): Tool to locate python wheel file in an index + pure (bool): Whether the wheel resolver tool should only look for a pure (includes no compiled extensions) Python + wheel. Defaults to looking both pure and platform (includes compiled extensions) wheels. + Only valid if tool is passed or Plugin.Python.WheelTool is set. """ binary = binary or entry_points package_name = package_name or name.replace('-', '_') @@ -623,6 +626,8 @@ def python_wheel(name:str, version:str, labels:list=[], hashes:list=None, packag # Try the URLs generated using the wheel name schemes. If those fail, try # generating a url with the wheel_resolver tool and download that if successful. cmd = f'$TOOLS_PYTHON $TOOLS_RESOLVER --package {package_name} --version {version} --prereleases {prereleases} --verbosity {tool_verbosity}' + if pure: + cmd += ' --abi none --platform any' if urls: cmd += ''.join([' --urls %s' % url for url in urls]) file_rule = build_rule( @@ -640,6 +645,8 @@ def python_wheel(name:str, version:str, labels:list=[], hashes:list=None, packag sandbox = False, ) else: + if pure: + fail("pure can only be passed if either tool is passed as well or Plugin.Python.WheelTool is set") if not urls: fail('python.wheel_repo is not set in the config, must pass repo explicitly to python_wheel') file_rule = remote_file( diff --git a/third_party/python/BUILD b/third_party/python/BUILD index 2dd8db7..4005c88 100644 --- a/third_party/python/BUILD +++ b/third_party/python/BUILD @@ -423,6 +423,7 @@ python_wheel( zip_safe = False, # There doesn't seem to be a predictable URL for this version of debugpy so we need to resolve it instead. tool = "//tools:wheel_resolver", + pure = True, ) python_wheel(