Set up NumPy dev env with VSCode debugging


Compile Python with debug build

# setup the source path for later debugging
export PYTHON_BUILD_BUILD_PATH=$HOME/pythondev/builds/3.12
# build a debug version of Python
pyenv install 3.12 -g

Set up NumPy dev env

# install build deps, see https://numpy.org/doc/stable/building/index.html
sudo apt install -y gcc g++ gfortran libopenblas-dev liblapack-dev pkg-config python3-pip python3-dev

# clone numpy sources
git clone  https://github.com/numpy/numpy.git
cd numpy
git submodule update --init

# automatically use the python debug build in cwd
pyenv local 3.12

# in case you don't want to pollute the global env
python -m pip install --user virtualenv
virtualenv venv

# build numpy without optimization
spin build --clean -- -Dbuildtype=debug -Ddisable-optimization=true

Debugging C code

I found that manually setting everything needed is pretty straightforward, and we can stick to the spin workflow.

Add a gdb launch conf to your launch.json:

// "configurations": [
{
  // ...
  "program": "YOUR_WORKING_DIR/venv/bin/python",
  "args": [
    // Don't prepend current dir to `sys.path`
    // See https://docs.python.org/3/using/cmdline.html#cmdoption-P
    "-P",
    "whatever_you_wanna_debug.py",
  ],
  // ...
  "environment": [
    {
      // instead manually set `PYTHONPATH`
      "name": "PYTHONPATH",
      "value": "YOUR_WORKING_DIR/build-install/usr/lib/python3.12/site-packages"
    }
  ],
  // ...
}
// ...

Debugging Python code

For env variables, PYTHONSAFEPATH does not work but PYTHONPATH does, so I just set python launch args to -P.

This time, create a Python debugger launch profile:

// "configurations": [
{
  // ...
  "python": "YOUR_WORKING_DIR/venv/bin/python",
  "pythonArgs": ["-P"],
  "program": "whatever.py",
  // ...
  "env": {
    // note the inconsistent env config style
    "PYTHONPATH": "YOUR_WORKING_DIR/build-install/usr/lib/python3.12/site-packages"
  },
  "justMyCode": false,
  // ...
}
// ...