Skip to content

Instantly share code, notes, and snippets.

@mennucc
Created November 14, 2025 08:16
Show Gist options
  • Select an option

  • Save mennucc/bc815e1fa234e2d1adddb0e2a96c3006 to your computer and use it in GitHub Desktop.

Select an option

Save mennucc/bc815e1fa234e2d1adddb0e2a96c3006 to your computer and use it in GitHub Desktop.
wingware wingdb with python autodetection
#!/bin/bash
# Script used to debug sub-processes launched via sys.executable
# We replace sys.executable with this script, which inserts code
# that starts debugging before the users's module is invoked.
# The command line contains the file name to debug and its arguments
# The debugger is configured using the following envs:
#
# WINGDB_PYTHON -- The Python to use for debugging (default=python)
# WINGDB_HOSTPORT -- The hostname:port to connect to (default=localhost:50005)
# WINGDB_PYARGS -- Any arguments to pass to Python. Defaults to -u.
# Set this to '-' to not pass any arguments.
#
# See the manual for other supported WINGDB_* environment variables.
# Function to extract Python interpreter from shebang
get_python_from_shebang() {
local script_file="$1"
# Check if file exists and is readable
if [ ! -f "${script_file}" ] || [ ! -r "${script_file}" ]; then
return 1
fi
# Read first line
local shebang=$(head -n 1 "${script_file}")
# Check if it starts with #!
case "${shebang}" in
'#!'*)
;;
*)
return 1
;;
esac
# Extract the interpreter
# Handle both direct paths like #!/usr/bin/python3
# and env-based like #!/usr/bin/env python3
case "${shebang}" in
'#!'*'/env '*)
# env-based shebang - extract command after 'env'
echo "${shebang}" | sed 's|^#!.*/env[[:space:]]*||' | awk '{print $1}'
return 0
;;
'#!'*)
# direct path shebang
echo "${shebang}" | sed 's|^#!||' | awk '{print $1}'
return 0
;;
esac
return 1
}
# Check for required args - initially leave empty if not set
if [ "${WINGDB_HOSTPORT}" = "" ]; then
WINGDB_HOSTPORT=localhost:50005
export WINGDB_HOSTPORT
fi
# Set up WINGHOME
if [ "${WINGHOME}" = "" ]; then
WINGHOME=`dirname "$0"`
WINGHOME=$(cd "${WINGHOME}"; pwd)
export WINGHOME
fi
# Determine if there are extra args for Python
if [ "${WINGDB_PYARGS}" = "" ]; then
WINGDB_PYARGS=-u
elif [ "${WINGDB_PYARGS}" = "-" ]; then
WINGDB_PYARGS=
fi
# Determine if passing a command with -c or module name with -m. If so, modify it to initiate debug
COMMAND=
MODULE=
PYARGS=()
PYARGS_POS=1
ARGS=()
ARGS_POS=1
SEEN_NON_PYARG=0
NEXT_IS_COMMAND=0
NEXT_IS_MODULE=0
TARGET_SCRIPT=
for ((i = 1; i <= $#; i++)); do
ARG=${!i}
if [ "${NEXT_IS_COMMAND}" == "1" ]; then
NEXT_IS_COMMAND=0
COMMAND="import sys; sys.path.append('''${WINGHOME}'''); import wingdbstub; del sys; ${ARG}"
PYARGS[${PYARGS_POS}]=\"${COMMAND}\"
PYARGS_POS=$[PYARGS_POS + 1]
elif [ "${NEXT_IS_MODULE}" == "1" ]; then
NEXT_IS_MODULE=0
MODULE="${ARG}"
SEEN_NON_PYARG=1
elif [ ${SEEN_NON_PYARG} = 0 ] && [ "${ARG}" = "-c" ]; then
PYARGS[${PYARGS_POS}]=-c
PYARGS_POS=$[PYARGS_POS + 1]
NEXT_IS_COMMAND=1
elif [ ${SEEN_NON_PYARG} = 0 ] && [ "${ARG}" = "-m" ]; then
NEXT_IS_MODULE=1
elif [ ${SEEN_NON_PYARG} = 0 ] && [ "${ARG:0:1}" = "-" ]; then
PYARGS[${PYARGS_POS}]=${ARG}
PYARGS_POS=$[PYARGS_POS + 1]
elif [ "${COMMAND}" != "" ]; then
PYARGS[${PYARGS_POS}]=${ARG}
PYARGS_POS=$[PYARGS_POS + 1]
else
# Capture the target script for shebang detection
if [ -z "${TARGET_SCRIPT}" ]; then
TARGET_SCRIPT="${ARG}"
fi
ARGS[${ARGS_POS}]=${ARG}
ARGS_POS=$[ARGS_POS + 1]
SEEN_NON_PYARG=1
fi
done
# Try to detect Python version from shebang if WINGDB_PYTHON wasn't explicitly set
# and we're running a script file (not -c or -m)
if [ "${WINGDB_PYTHON}" = "" ] && [ -n "${TARGET_SCRIPT}" ] && [ -z "${COMMAND}" ] && [ -z "${MODULE}" ]; then
SHEBANG_PYTHON=$(get_python_from_shebang "${TARGET_SCRIPT}")
if [ $? -eq 0 ] && [ -n "${SHEBANG_PYTHON}" ]; then
# Check if it's a python-related interpreter
case "${SHEBANG_PYTHON}" in
python|python[0-9]|python[0-9].[0-9]*|python[0-9][0-9]|python[0-9][0-9].[0-9]*)
WINGDB_PYTHON="${SHEBANG_PYTHON}"
;;
esac
fi
fi
# If still not set, try to find an available Python interpreter
if [ "${WINGDB_PYTHON}" = "" ]; then
# Try to find an available Python interpreter
if command -v python3 >/dev/null 2>&1; then
WINGDB_PYTHON=python3
elif command -v python >/dev/null 2>&1; then
WINGDB_PYTHON=python
elif command -v python2 >/dev/null 2>&1; then
WINGDB_PYTHON=python2
else
echo "Error: No Python interpreter found in PATH" >&2
echo "Please install Python or set WINGDB_PYTHON environment variable" >&2
exit 1
fi
fi
export WINGDB_PYTHON
# Running code given on the command line with -c
if [ "${COMMAND}" != "" ]; then
#echo "COMMAND LINE:" "${WINGDB_PYTHON}" "${PYARGS[@]}"
eval exec "${WINGDB_PYTHON}" "${PYARGS[@]}"
# Loading and running a module with -m
elif [ "${MODULE}" != "" ]; then
export WINGDB_NAMEDMODULETORUN=${MODULE}
#echo "COMMAND LINE: ${WINGDB_PYTHON}" ${WINGDB_PYARGS} "${PYARGS[@]}" "${WINGHOME}/bootstrap/wingdb.py" "${ARGS[@]}"
eval exec "${WINGDB_PYTHON}" ${WINGDB_PYARGS} "${PYARGS[@]}" "${WINGHOME}/bootstrap/wingdb.py" "${ARGS[@]}"
# Running a Python source file
else
#echo "COMMAND LINE:" "${WINGDB_PYTHON}" ${WINGDB_PYARGS} "${PYARGS[@]}" "${WINGHOME}/bootstrap/wingdb.py" "${ARGS[@]}"
exec "${WINGDB_PYTHON}" ${WINGDB_PYARGS} "${PYARGS[@]}" "${WINGHOME}/bootstrap/wingdb.py" "${ARGS[@]}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment