Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6e3e952
fix: reconstruct PKG-15601 CF-align onto master
skupr-anaconda Sep 21, 2026
5adfe34
fix: align the recipe's build scripts and meta.yaml with cf
skupr-anaconda Sep 21, 2026
e7a7de2
fix: disable unix debug python variants (PKG-2624)
skupr-anaconda Sep 22, 2026
472fcc8
fix: list libpython and cpython in anaconda.yaml
skupr-anaconda Sep 23, 2026
8921d05
fix: re-enable unix debug python for testing dest
skupr-anaconda Sep 23, 2026
20e2de6
feat(recipe): isolate unix Py_DEBUG on py315-debug
skupr-anaconda Sep 24, 2026
be02563
fix(recipe): skip win so debug-only CBC renders
skupr-anaconda Sep 24, 2026
ad0cedb
fix(recipe): host libexpat so debug pyexpat links
skupr-anaconda Sep 24, 2026
2a5b32f
feat(recipe): enable win-64 PCbuild -d debug
skupr-anaconda Sep 24, 2026
bf621e9
fix(recipe): pin libexpat on python run
skupr-anaconda Sep 24, 2026
8dcb7f1
fix(recipe): ignore win CRT run_exports on debug
skupr-anaconda Sep 24, 2026
7ece225
fix(recipe): stage win debug python.exe and venv launchers
skupr-anaconda Sep 24, 2026
33e43e8
fix: drop unix debug from CF-align (owned by #258)
skupr-anaconda Sep 24, 2026
226ab8c
fix: pin libexpat on python host and run
skupr-anaconda Sep 24, 2026
98ff6b0
fix(recipe): use win debug import-lib names in tests
skupr-anaconda Sep 24, 2026
b11c226
fix(recipe): fix win debug test yaml and cmake ABI
skupr-anaconda Sep 24, 2026
6e1bb94
Revert "fix: pin libexpat on python host and run"
skupr-anaconda Sep 25, 2026
9872548
fix(recipe): drop glued win lib tests; stage tkinter FT lib
skupr-anaconda Sep 25, 2026
f1fd74d
fix(recipe): normalize test command yaml indent
skupr-anaconda Sep 25, 2026
c10dd05
fix(recipe): merge cf-align; skip win debug cmake tests
skupr-anaconda Sep 25, 2026
c720eb7
fix(recipe): unindent libpython-static and cpython outputs
skupr-anaconda Sep 25, 2026
5349314
fix(recipe): skip aarch64 main bootstrap; FT tkinter lib
skupr-anaconda Sep 25, 2026
ee300b9
fix(recipe): stage win FT venvlauncher without _d
skupr-anaconda Sep 28, 2026
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
2 changes: 0 additions & 2 deletions .gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions abs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ build_parameters:
- "--error-overlinking"
- "--error-overdepending"

# Upload testing artifacts: ad-testing/label/py315
# Upload testing artifacts: ad-testing/label/py315-debug (PKG-2624 spike).
# Release 3.15 stays on PR #256 → ad-testing/label/py315.
upload_channels:
- ad-testing/label/py315
- ad-testing/label/py315-debug

build_env_vars:
ANACONDA_ROCKET_ENABLE_PY315: yes
4 changes: 3 additions & 1 deletion anaconda.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ upstream_sources:
from_pattern: ^v(\d+\.\d+\.\d+)$
to_pattern: \1
packages:
- libpython-static
- python
- libpython
- libpython-static
- cpython
- python-freethreading
- python-gil
- python-jit
Expand Down
111 changes: 111 additions & 0 deletions recipe/DEBUG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Py_DEBUG spike (PKG-2624)

Time-boxed technical spike stacked on python-feedstock#256. **Not pkgs/main.** Product ticket PKG-2624 is closed (no market).

## What this is (and is not)

| Build | What you get | What you do not get |
|-------|----------------|---------------------|
| **Unix** (`--with-pydebug`) | `Py_DEBUG`, `'d' in sys.abiflags`, `sys.gettotalrefcount()`, `libpython3.15d.so` / `libpython3.15td.so` | DWARF-complete unstripped objects (conda-build may strip `.symtab` / `.debug_info`) |
| **Windows** (`PCbuild -d`) | `python315_d.lib` / `python3_d.lib` / `_tkinter_d.lib`, `gettotalrefcount`, debug CRT | Not the same as Unix `abiflags` (`sys.abiflags` is Unix-only) |
| **`python -X dev`** | Runtime development checks on a **release** interpreter | `d` ABI, refcount APIs, debug libpython |

Do not confuse Py_DEBUG / PCbuild `-d` with `-X dev`. This dest ships debug interpreters on unix **and** win-64.

## Gate: keep debug off pkgs/main

PBP `upload_channels` is **graph-wide**. Do **not** zip `channel_targets` with `python_debug` (F94). The dummy `channel_targets = ('abc','def')` in `meta.yaml` exists so the linter expands and `'conda-forge' in channel_targets` is false — leave it.

| File | Debug spike (this PR) | Before pkgs/main / #256-style py315 |
|------|------------------------|--------------------------------------|
| `recipe/conda_build_config.yaml` | `build_type: debug` only; `freethreading: yes/no`; unix+win | Restore `release` (and drop `debug` unless dest is still a testing label) |
| `abs.yaml` | `upload_channels: [ad-testing/label/py315-debug]` | `#256` keeps `ad-testing/label/py315`. Never point debug variants at `main` |

Release 3.15 stays on **#256** → `ad-testing/label/py315`. This PR is a **second graph**.

## Pinning a debug interpreter

Build string contains `_debug_` plus the ABI tag:

```text
python 3.15.* *_debug_cp315 # GIL debug
python 3.15.* *_debug_cp315t # free-threading debug
```

`run_exports` (when `build_type == debug`) already pins:

```text
python {{ ver2 }}.* *_debug_{{ abi_tag }}
```

Downstream recipes that must link the debug ABI should depend on that pin, **not** on a generic `python 3.15.*`.

Debug Python **cannot load release extensions** (and vice versa). `abiflags` `d` / `td` vs release `''` / `t` are different ABIs. Mixing them is a loader/ABI error, not a solver hint.

## Matrix

- `freethreading: yes/no` × `build_type: debug`
- **No `release` on this graph**
- GIL debug lib: `libpython3.15d.so` (`abiflags` contains `d`)
- FT debug lib: `libpython3.15td.so` (`abiflags` contains `td`; assert `'d' in sys.abiflags` covers both)
- Windows: PCbuild `-d`. Import libs in `libs\`: `python315_d.lib` / `python315t_d.lib`, `python3_d.lib` / `python3t_d.lib`, `_tkinter_d.lib`. Do not add a win **release** variant onto `py315-debug`.

## Local conda-build

```bash
export ANACONDA_ROCKET_ENABLE_PY315=yes
cd /home/skupr/src/aggregate/python-feedstock
conda-build recipe --suppress-variables --error-overlinking --error-overdepending \
-c defaults --override-channels
```

CBC is already debug-only on this branch, so omit `--variants`. Prefix:

```text
conda-bld/linux-64/python-3.15.0rc2-*_debug_cp315*.conda
```

On a tree that still has `release` (e.g. #256 HEAD) force one variant:

```bash
conda-build recipe --suppress-variables --error-overlinking --error-overdepending \
-c defaults --override-channels \
--variants "{'build_type': 'debug', 'freethreading': 'no'}"
```

`build_base.sh` already passes `--with-pydebug`, disables PGO/JIT on debug, and names `libpython${VERABI}`. Do not rewrite it unless a build proves a bug.

## ABI tests (CI)

Unconditional on this graph (`meta.yaml` `commands` + `run_test.py`). Do **not** rely on `PY_INTERP_DEBUG` — that is `script_env` (build), not the test env.

```bash
python -c "import sys; assert 'd' in sys.abiflags; assert hasattr(sys, 'gettotalrefcount'); print(sys.abiflags, sys.gettotalrefcount())"
```

Existing `libpython${VERABI}` tests already append `d` / `td`. Linux `libpython3.so` is gated `unix and build_type == "release"` (empty upstream for debug); leave it.

CMake `Python_FIND_ABI` already turns debug ON when `build_type == debug`.

## gdb / lldb / ELF (local only — not a PBP gate)

```bash
# GIL debug; FT: libpython3.15td.so
LIB=$PREFIX/lib/libpython3.15d.so
readelf -WS "$LIB" # .dynsym required; .symtab / .debug_info may be stripped
readelf -d "$LIB"
nm -D "$LIB"

gdb -q "$PREFIX/bin/python" --batch -ex "set pagination off" \
-ex "run -c 'import os; os.abort()'" -ex bt -ex quit
lldb -b -o "run -c 'import os; os.abort()'" -o bt -o quit "$PREFIX/bin/python"
```

If gdb backtraces are shallow, that is strip quality, not a missing `Py_DEBUG`. Do not expand this spike to unstrip unless it is a one-line recipe change. Use `/debug-elf` for RPATH/SONAME/arch, not for solver or graph triage.

## Out of scope

- numpy / pybind11 debug extension chain (follow-on after this python graph publishes to `py315-debug`; numpy-feedstock currently `skip: true # [py>=315]`)
- conda-forge `python_debug` `zip_keys` / real `channel_targets`
- pkgs/main, sanitizer/valgrind builds, commercial packaging
- Merging this PR (human-only; never pkgs/main)
25 changes: 21 additions & 4 deletions recipe/build_base.bat
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ if "%DEBUG_C%"=="yes" (
:: AP doesn't support PGO atm?
set PGO=

if "%PY_GIL_DISABLED%" == "yes" (
if "%PY_FREETHREADING%" == "yes" (
set "FREETHREADING=--disable-gil"
set "THREAD=t"
set "EXE_T=%VER%t"
Expand All @@ -75,6 +75,13 @@ set TCLTK_MSBUILD_PROPS="/p:TclVersion=%tk%" "/p:TkVersion=%tk%"

cd PCbuild

:: CF (skipped): CONDA_BUILD_CROSS_COMPILATION host-vs-build extra MSBuild.
:: AR native workers only; ARCH/BUILD_PATH above, not CF HOST_DIR/BUILD_DIR.
:: if "%CONDA_BUILD_CROSS_COMPILATION%" == "1" (
:: set LIBRARY_PREFIX=%BUILD_PREFIX%\\Library
:: call build.bat %CONFIG% %FREETHREADING% -m -e -v -p %BUILD_PLATFORM% %TCLTK_MSBUILD_PROPS%
:: )

:: Twice because:
:: error : importlib_zipimport.h updated. You will need to rebuild pythoncore to see the changes.
call build.bat %PGO% %CONFIG% %FREETHREADING% -m -e -v -p %PLATFORM% %TCLTK_MSBUILD_PROPS%
Expand All @@ -84,7 +91,7 @@ if errorlevel 1 exit 1
cd ..

:: Populate the root package directory
for %%x in (python%VERNODOTS%%THREAD%%_D%.dll python3%THREAD%%_D%.dll python%EXE_T%%_D%.exe pythonw%EXE_T%%_D%.exe) do (
for %%x in (python%VERNODOTS%%THREAD%%_D%.dll python3%THREAD%%_D%.dll python%EXE_T%%_D%.exe pythonw%EXE_T%%_D%.exe python%_D%.exe) do (
if exist %SRC_DIR%\PCbuild\%BUILD_PATH%\%%x (
copy /Y %SRC_DIR%\PCbuild\%BUILD_PATH%\%%x %PREFIX%
) else (
Expand Down Expand Up @@ -160,6 +167,8 @@ for %%x in (lib libs) do (
if errorlevel 1 exit 1
if exist %SRC_DIR%\PCbuild\%BUILD_PATH%\_tkinter%_D%.lib copy /Y %SRC_DIR%\PCbuild\%BUILD_PATH%\_tkinter%_D%.lib %PREFIX%\%%x\
if errorlevel 1 exit 1
if exist %SRC_DIR%\PCbuild\%BUILD_PATH%\_tkinter%THREAD%%_D%.lib copy /Y %SRC_DIR%\PCbuild\%BUILD_PATH%\_tkinter%THREAD%%_D%.lib %PREFIX%\%%x\
if errorlevel 1 exit 1
)


Expand All @@ -173,6 +182,9 @@ if errorlevel 1 exit 1
if exist %SRC_DIR%\PCbuild\%BUILD_PATH%\venvlauncher%THREAD%%_D%.exe (
@rem We did copy pythonw.exe until 3.12 but starting with 3.13 we seem to need the latter. Should we omit the first?
copy /Y %SRC_DIR%\PCbuild\%BUILD_PATH%\venvlauncher%THREAD%%_D%.exe %PREFIX%\lib\python\venv\scripts\nt\python.exe
copy /Y %SRC_DIR%\PCbuild\%BUILD_PATH%\venvlauncher%THREAD%%_D%.exe %PREFIX%\lib\python\venv\scripts\nt\venvlauncher.exe
:: FT venv copies venvlaunchert.exe when python.exe does not end in _d (CPython 3.15 Lib/venv).
copy /Y %SRC_DIR%\PCbuild\%BUILD_PATH%\venvlauncher%THREAD%%_D%.exe %PREFIX%\lib\python\venv\scripts\nt\venvlauncher%THREAD%.exe
copy /Y %SRC_DIR%\PCbuild\%BUILD_PATH%\venvlauncher%THREAD%%_D%.exe %PREFIX%\lib\python\venv\scripts\nt\venvlauncher%THREAD%%_D%.exe
) else (
echo "WARNING :: %SRC_DIR%\PCbuild\%BUILD_PATH%\venvlauncher%THREAD%%_D%.exe does not exist"
Expand All @@ -181,6 +193,8 @@ if exist %SRC_DIR%\PCbuild\%BUILD_PATH%\venvlauncher%THREAD%%_D%.exe (
if exist %SRC_DIR%\PCbuild\%BUILD_PATH%\venvwlauncher%THREAD%%_D%.exe (
@rem We did copy pythonw.exe until 3.12 but starting with 3.13 we seem to need the latter. Should we omit the first?
copy /Y %SRC_DIR%\PCbuild\%BUILD_PATH%\venvwlauncher%THREAD%%_D%.exe %PREFIX%\lib\python\venv\scripts\nt\pythonw.exe
copy /Y %SRC_DIR%\PCbuild\%BUILD_PATH%\venvwlauncher%THREAD%%_D%.exe %PREFIX%\lib\python\venv\scripts\nt\venvwlauncher.exe
copy /Y %SRC_DIR%\PCbuild\%BUILD_PATH%\venvwlauncher%THREAD%%_D%.exe %PREFIX%\lib\python\venv\scripts\nt\venvwlauncher%THREAD%.exe
copy /Y %SRC_DIR%\PCbuild\%BUILD_PATH%\venvwlauncher%THREAD%%_D%.exe %PREFIX%\lib\python\venv\scripts\nt\venvwlauncher%THREAD%%_D%.exe
) else (
echo "WARNING :: %SRC_DIR%\PCbuild\%BUILD_PATH%\venvwlauncher%THREAD%%_D%.exe does not exist"
Expand All @@ -200,8 +214,11 @@ move %PREFIX%\lib\python\test_keep %PREFIX%\lib\python\test
if errorlevel 1 exit 1

:: We need our Python to be found!
if "%_D%" neq "" copy %PREFIX%\python%_D%.exe %PREFIX%\python.exe
if "%EXE_T%" neq "" copy %PREFIX%\python%EXE_T%.exe %PREFIX%\python.exe
:: GIL debug: python_d.exe; FT debug: python3.15t_d.exe; skip when already python.exe.
if not "%EXE_T%%_D%"=="" (
copy /Y %PREFIX%\python%EXE_T%%_D%.exe %PREFIX%\python.exe
if errorlevel 1 exit 1
)

set "PYTHON=%PREFIX%\python.exe"
:: bytecode compile the standard library
Expand Down
Loading