How to Install Python 3.13 on Debian 13, 12 and 11

Install Python 3.13 on Debian 13, 12, or 11 with APT on Trixie, Python.org source builds, venv setup, updates, fixes, and removal.

PublishedAuthorJoshua JamesRead time10 minGuide typeDebian

Python 3.13 on Debian depends on the release you run: Debian 13 (Trixie) already ships the 3.13 branch through APT, while Debian 12 (Bookworm) and Debian 11 (Bullseye) stay on older default interpreters. Install the Debian package on Trixie for normal development, or build CPython 3.13 from Python.org source on Bookworm and Bullseye when a project needs that exact branch.

Both paths keep Debian’s package-owned /usr/bin/python3 intact. Use versioned commands, build into a separate prefix for source installs, and put project dependencies inside virtual environments instead of changing the system Python.

Install Python 3.13 on Debian

Choose the Python 3.13 Installation Method

Start by matching the method to your Debian release. Debian 13 provides python3.13 in the default stable archive, but Debian 12 and Debian 11 do not expose that package from their normal stable sources.

MethodSupported Debian ReleaseSourceUpdate BehaviorBest For
Debian APT packageDebian 13 (Trixie)Debian stable packagesAPT updates from DebianMost Trixie systems that need Debian-maintained Python 3.13
Python.org source buildDebian 12 and Debian 11; optional side install on Debian 13Latest Python 3.13 source releaseManual rebuild with the helper scriptBookworm, Bullseye, or Trixie projects that need the newest upstream 3.13.x release beside Debian’s interpreter
Testing, unstable, or Ubuntu PPA packagesNot a stable Debian methodMixed or foreign package sourcesNot recommended hereAvoid on stable systems because it can create dependency conflicts

Use the APT method on Debian 13 when Debian-maintained security updates and package integration matter most. Use the source method on Debian 12 or Debian 11 instead of adding Debian testing, unstable, or Ubuntu PPAs to a stable host. On Debian 13, the source method is still useful as a side install when a project needs the newest upstream 3.13.x release before Debian packages move to that point release.

For projects that require the newer CPython 3.14 branch instead, use the Python 3.14 on Debian workflow rather than adapting 3.13 commands by hand.

Protect Debian’s Default Python

Debian uses its package-managed Python interpreter for system tools, APT hooks, desktop utilities, and packaged Python modules. Changing /usr/bin/python3 or replacing package-owned files can break more than a single project.

  • Use versioned commands: Run python3.13 for this branch instead of changing the unversioned python3 command.
  • Use virtual environments: Install project libraries inside a venv so pip writes into the project environment, not Debian’s package-managed Python directories.
  • Use a separate prefix for source builds: The default source method installs under /usr/local/python3.13 with make altinstall; the Debian 13 upstream side install uses /usr/local/python3.13-upstream.
  • Avoid unsupported switching: Do not create a custom update-alternatives family for /usr/bin/python3, do not overwrite symlinks, and do not remove Debian’s default Python branch.

Check Your Debian Release and Current Python

Confirm the Debian release before choosing a method:

. /etc/os-release
printf '%s\n' "$PRETTY_NAME"
python3 --version
python3.13 --version 2>/dev/null || echo "python3.13 is not installed yet"

Debian 13 normally reports Python 3.13 for both python3 and python3.13:

Debian GNU/Linux 13 (trixie)
Python 3.13.5
Python 3.13.5

Debian 12 and Debian 11 report older default interpreters and no python3.13 command from the default stable sources until you add the source-built interpreter.

Install Python 3.13 with APT on Debian 13

Refresh APT metadata before installing the versioned interpreter helpers:

sudo apt update

If your account cannot use sudo yet, configure administrator access with add a user to sudoers on Debian, or run the privileged commands from a root shell.

Install the interpreter, venv support, and development headers from Debian 13’s default repositories:

sudo apt install python3.13 python3.13-venv python3.13-dev

The python3.13-venv package supplies the wheels needed for virtual environments. The python3.13-dev package adds headers for packages that compile C extensions against Python 3.13.

Verify the Debian package and core runtime modules:

python3.13 --version
python3.13 -c "import ssl, sqlite3, bz2, lzma, zlib, ctypes, readline; print('Python 3.13 ready on Debian')"
Python 3.13.5
Python 3.13 ready on Debian

Debian may backport security fixes to its packaged 3.13.5 branch instead of tracking the newest upstream 3.13.x point release. Use the source method only when your project needs the latest upstream maintenance release rather than the Debian-maintained package.

Prepare Debian for a Python 3.13 Source Build

Debian 12 and Debian 11 need build tools and development headers before compiling CPython. Debian 13 needs the same prerequisites only when you choose the optional upstream side install. Refresh package metadata first:

sudo apt update

Install the compiler, download tool, and library headers for SSL, SQLite, compression modules, readline, Tkinter, UUID, dbm, and other standard-library extension modules:

sudo apt install ca-certificates wget python3 build-essential zlib1g-dev libncurses-dev \
libgdbm-dev libgdbm-compat-dev libnss3-dev libssl-dev libsqlite3-dev libreadline-dev \
libffi-dev libbz2-dev liblzma-dev uuid-dev libexpat1-dev tk-dev pkg-config make libdb-dev

Check that the host still has several gigabytes free for the source archive, extracted tree, object files, logs, and installed prefix:

df -h "$HOME" /usr/local

The default source build uses the home directory for the temporary workspace and /usr/local/python3.13 for the installed interpreter. The Debian 13 upstream side install uses a different prefix later so it does not collide with the packaged interpreter.

Create a Python 3.13 Source Build Helper

The helper resolves the current Python 3.13 maintenance release from Python.org, reads the release-page SHA-256 checksum for the XZ source tarball, verifies the download, checks the target command name before building or declaring an install current, installs CPython with make altinstall, and creates a guarded command link or wrapper only when it will not shadow an existing command. It leaves configure, make, and install logs in the build directory for troubleshooting.

cat <<'EOF' > install-python313-source-debian.sh
#!/usr/bin/env bash
# LinuxCapable Python 3.13 source helper
set -euo pipefail

INSTALL_PREFIX="${INSTALL_PREFIX:-/usr/local/python3.13}"
BUILD_DIR="${BUILD_DIR:-$HOME/python3.13-source-build}"
PY313_COMMAND_NAME="${PY313_COMMAND_NAME:-python3.13}"
PY313_BIN="$INSTALL_PREFIX/bin/python3.13"
PY313_FORCE_REBUILD="${PY313_FORCE_REBUILD:-0}"

validate_settings() {
	if [[ -z "$INSTALL_PREFIX" || "$INSTALL_PREFIX" != /* ]]; then
		printf 'INSTALL_PREFIX must be an absolute path.\n' >&2
		exit 1
	fi

	if [[ -z "$PY313_COMMAND_NAME" || "$PY313_COMMAND_NAME" == */* || "$PY313_COMMAND_NAME" =~ [[:space:]] ]]; then
		printf 'PY313_COMMAND_NAME must be a command name, not a path or a value with spaces.\n' >&2
		exit 1
	fi
}

require_cmd() {
	if ! command -v "$1" >/dev/null 2>&1; then
		printf 'Missing required command: %s\n' "$1" >&2
		exit 1
	fi
}

validate_settings

for cmd in python3 awk; do
	require_cmd "$cmd"
done

mkdir -p "$BUILD_DIR"

require_link_cmds() {
	for cmd in sudo readlink grep mktemp install ln; do
		require_cmd "$cmd"
	done
}

require_build_cmds() {
	for cmd in wget tar make gcc sha256sum nproc tail; do
		require_cmd "$cmd"
	done
	require_link_cmds
}

is_managed_wrapper() {
	local path="$1"
	local target="$2"
	[ -f "$path" ] && grep -Fqx '# LinuxCapable Python 3.13 source wrapper' "$path" && grep -Fqx "PY313_SOURCE_TARGET='$target'" "$path"
}

write_command_wrapper() {
	local target="$1"
	local link="$2"
	local tmp_file=""

	tmp_file="$(mktemp)"
	{
		printf '%s\n' '#!/usr/bin/env sh'
		printf '%s\n' '# LinuxCapable Python 3.13 source wrapper'
		printf "PY313_SOURCE_TARGET='%s'\n" "$target"
		# shellcheck disable=SC2016
		printf '%s\n' 'exec "$PY313_SOURCE_TARGET" "$@"'
	} >"$tmp_file"
	sudo install -m 0755 "$tmp_file" "$link"
	rm -f "$tmp_file"
}

check_command_target_safe() {
	local target="$1"
	local link="/usr/local/bin/$PY313_COMMAND_NAME"
	local existing_path=""
	local existing_target=""

	if existing_path="$(command -v "$PY313_COMMAND_NAME" 2>/dev/null)"; then
		existing_target="$(readlink -f "$existing_path" 2>/dev/null || true)"
		if [ -n "$existing_target" ] && [ "$existing_target" != "$target" ] && ! is_managed_wrapper "$existing_path" "$target"; then
			printf 'Refusing to shadow existing %s at %s\n' "$PY313_COMMAND_NAME" "$existing_path" >&2
			printf 'Set PY313_COMMAND_NAME to a separate name, such as python3.13-upstream, when another package owns the command.\n' >&2
			exit 1
		fi
	fi

	if [ -e "$link" ] && [ ! -L "$link" ] && ! is_managed_wrapper "$link" "$target"; then
		printf 'Refusing to overwrite unmanaged path: %s\n' "$link" >&2
		exit 1
	fi
}

install_command_link() {
	local target="$1"
	local link="/usr/local/bin/$PY313_COMMAND_NAME"

	check_command_target_safe "$target"

	if [ "$PY313_COMMAND_NAME" = "python3.13" ]; then
		sudo ln -sfn "$target" "$link"
	else
		write_command_wrapper "$target" "$link"
	fi
}

fetch_release_metadata() {
	python3 - <<'PY'
import gzip
import re
from urllib.request import urlopen

release_html = urlopen("https://www.python.org/downloads/latest/python3.13/", timeout=20).read()
if release_html.startswith(b"\x1f\x8b"):
    release_html = gzip.decompress(release_html)
release_html = release_html.decode("utf-8")

version_match = re.search(r'<h1 class="page-title">Python (3\.13\.\d+)</h1>', release_html)
if not version_match:
    raise SystemExit("Could not find the latest Python 3.13 release version")
version = version_match.group(1)

row = re.search(
    r'<tr>\s*<td><a href="(?P<url>[^"]*Python-' + re.escape(version) + r'\.tar\.xz)">XZ compressed source tarball</a></td>.*?<code class="checksum">(?P<checksum>.*?)</code>',
    release_html,
    re.S,
)
if not row:
    raise SystemExit("Could not find the XZ source tarball checksum")

checksum_text = re.sub(r"<[^>]+>", "", row.group("checksum"))
sha256 = re.sub(r"[^0-9a-f]", "", checksum_text)
if len(sha256) != 64:
    raise SystemExit(f"Unexpected SHA-256 checksum length: {len(sha256)}")

print(f"PY313_VERSION='{version}'")
print(f"PY313_URL='{row.group('url')}'")
print(f"PY313_SHA256='{sha256}'")
PY
}

run_logged() {
	local label="$1"
	shift
	local log_file="$BUILD_DIR/${label}-${PY313_VERSION}.log"
	if "$@" >"$log_file" 2>&1; then
		printf '%s complete; see %s\n' "$label" "${label}-${PY313_VERSION}.log"
	else
		printf '%s failed; last log lines:\n' "$label" >&2
		tail -n 50 "$log_file" >&2 || true
		exit 1
	fi
}

metadata_file="$BUILD_DIR/python313-release.env"
fetch_release_metadata >"$metadata_file"
# shellcheck source=/dev/null
. "$metadata_file"

printf 'Using Python %s\n' "$PY313_VERSION"

if [ -x "$PY313_BIN" ]; then
	current_version="$("$PY313_BIN" --version | awk '{print $2}')"
	if [ "$current_version" = "$PY313_VERSION" ] && [ "$PY313_FORCE_REBUILD" != "1" ]; then
		require_link_cmds
		install_command_link "$PY313_BIN"
		printf 'Python %s already installed at %s\n' "$current_version" "$PY313_BIN"
		exit 0
	fi
fi

require_build_cmds
check_command_target_safe "$PY313_BIN"

cd "$BUILD_DIR"
archive="Python-${PY313_VERSION}.tar.xz"
srcdir="Python-${PY313_VERSION}"

sudo rm -rf -- "$srcdir"
rm -f -- "$archive"
wget -q -O "$archive" "$PY313_URL"
printf '%s  %s\n' "$PY313_SHA256" "$archive" | sha256sum -c -
tar -xf "$archive"

cd "$srcdir"
configure_args=(--with-ensurepip=install "--prefix=$INSTALL_PREFIX")
if [ -n "${PY313_CONFIGURE_EXTRA:-}" ]; then
	# shellcheck disable=SC2206
	extra_args=($PY313_CONFIGURE_EXTRA)
	configure_args+=("${extra_args[@]}")
fi

run_logged configure ./configure "${configure_args[@]}"
run_logged make make -j"$(nproc)"
run_logged altinstall sudo make altinstall

printf '%s\n' "$INSTALL_PREFIX/lib" | sudo tee "/etc/ld.so.conf.d/${PY313_COMMAND_NAME}.conf" >/dev/null
sudo ldconfig

if [ -x "$PY313_BIN" ]; then
	install_command_link "$PY313_BIN"
	"$PY313_BIN" --version
	cd "$BUILD_DIR"
	sudo rm -rf -- "$srcdir"
	rm -f -- "$archive"
else
	printf 'Build completed, but %s was not found.\n' "$PY313_BIN" >&2
	exit 1
fi
EOF
chmod +x install-python313-source-debian.sh

Review the helper before running it. The chmod +x step makes the file executable; use the chmod command guide if you want more detail on executable bits.

Build and Install Python 3.13 from Source on Debian 12 or 11

On Debian 12 or Debian 11, start the build from the directory that contains the helper. On Debian 13, skip this default command and use the separate side-install command in the next section so the packaged python3.13 command stays untouched:

./install-python313-source-debian.sh

Relevant output includes the resolved 3.13.x release, checksum result, build phases, and installed interpreter version:

Using Python 3.13.13
Python-3.13.13.tar.xz: OK
configure complete; see configure-3.13.13.log
make complete; see make-3.13.13.log
altinstall complete; see altinstall-3.13.13.log
Python 3.13.13

The exact point release will change as Python.org publishes newer 3.13 maintenance releases. The checksum line must report OK; stop if it reports a mismatch.

Install Upstream Python 3.13 Alongside Debian 13 APT

Debian 13’s packaged python3.13 remains the best default for system integration, but Debian stable packages may not move to every upstream 3.13.x point release immediately. When a project needs the newest upstream maintenance release sooner, run the source helper with a separate prefix and command name so the Debian package stays untouched:

INSTALL_PREFIX=/usr/local/python3.13-upstream \
PY313_COMMAND_NAME=python3.13-upstream \
./install-python313-source-debian.sh

Verify the side-installed interpreter with its separate command:

python3.13-upstream --version

Use python3.13-upstream only for projects that need the upstream point release. Keep Debian’s packaged python3.13 for normal Trixie workflows unless you have a project-specific reason to use the side install.

Install the helper as the manual update command after the first successful source build:

sudo install -m 0755 install-python313-source-debian.sh /usr/local/bin/update-python313-source

Confirm the update helper is available through your normal command path:

command -v update-python313-source
/usr/local/bin/update-python313-source

If you used the Debian 13 upstream side install, add a separate update wrapper that keeps the custom prefix and command name attached to the rebuild:

sudo tee /usr/local/bin/update-python313-upstream >/dev/null <<'EOF'
#!/usr/bin/env bash
# LinuxCapable Python 3.13 upstream update wrapper
export INSTALL_PREFIX=/usr/local/python3.13-upstream
export PY313_COMMAND_NAME=python3.13-upstream
exec /usr/local/bin/update-python313-source "$@"
EOF
sudo chmod 0755 /usr/local/bin/update-python313-upstream

Confirm the side-install update wrapper is also available through your command path:

command -v update-python313-upstream
/usr/local/bin/update-python313-upstream

Verify the Python 3.13 Source Build

For the Debian 12 or Debian 11 default source install, verify the versioned command and the standard-library modules most likely to reveal missing development headers:

python3.13 --version
python3.13 -c "import ssl, sqlite3, bz2, lzma, zlib, ctypes, readline, tkinter, dbm.gnu, dbm.sqlite3; print('Python 3.13 source build ready on Debian')"
Python 3.13.13
Python 3.13 source build ready on Debian

Check pip through the default source-built interpreter. The exact pip version can change with Python maintenance releases, but the path should point under /usr/local/python3.13:

python3.13 -m pip --version

For the Debian 13 upstream side install, use python3.13-upstream for the same checks and expect paths under /usr/local/python3.13-upstream:

python3.13-upstream --version
python3.13-upstream -c "import ssl, sqlite3, bz2, lzma, zlib, ctypes, readline, tkinter, dbm.gnu, dbm.sqlite3; print('Python 3.13 upstream source build ready on Debian')"
python3.13-upstream -m pip --version

Use Python 3.13 Virtual Environments on Debian

Use Python 3.13 through virtual environments for project packages. A venv keeps dependencies away from Debian’s package-managed modules and makes the active interpreter obvious.

Create a Python 3.13 Virtual Environment

Create a reusable parent directory and initialize a Python 3.13 environment:

mkdir -p "$HOME/venvs"
python3.13 -m venv "$HOME/venvs/py313"

Use the side-install command instead when a Debian 13 project specifically needs the latest upstream point release:

mkdir -p "$HOME/venvs"
python3.13-upstream -m venv "$HOME/venvs/py313-upstream"

Activate the environment in the current shell. The source command matters because activation modifies only the shell process that reads the activation file:

source "$HOME/venvs/py313/bin/activate"

For the Debian 13 upstream side-install venv, activate $HOME/venvs/py313-upstream/bin/activate instead.

Inside the environment, python and pip should resolve to the venv:

python --version
python -m pip --version

Install project dependencies only after the venv is active:

python -m pip install --upgrade pip
python -m pip install package-name

Replace package-name with the library your project needs, such as requests, fastapi, or pytest. Keep application requirements in a project file such as requirements.txt or pyproject.toml instead of relying on terminal history.

Leave the Python 3.13 Virtual Environment

Deactivate the venv when you finish working in that project:

deactivate

The shell returns to the normal Debian context. The venv remains on disk until you remove its directory.

Avoid Global pip Changes on Debian

Do not use sudo python3 -m pip against Debian’s system interpreter, and do not use --break-system-packages as a routine workaround. Debian packages expect their Python modules to stay under package-manager control. Use venvs for project libraries and keep Python 3.13 as a versioned command.

Update Python 3.13 on Debian

Update Python 3.13 APT Packages on Debian 13

Debian 13 updates Python 3.13 through normal APT security and stable-update channels. Use a targeted upgrade when you only want to refresh the Python 3.13 package family already installed on the system:

sudo apt update
sudo apt install --only-upgrade python3.13 python3.13-venv python3.13-dev

The --only-upgrade flag upgrades those packages only if they are already installed. It will not install Python 3.13 on a Debian release where the package is absent.

Update a Source-Built Python 3.13 Install

Source-built Python does not update through APT. Rebuild it when Python.org publishes a newer 3.13.x maintenance release or when a security advisory affects your workloads:

update-python313-source

Use the dedicated wrapper when you built the Debian 13 upstream side install:

update-python313-upstream

For the default source helper, the no-op path prints the current version and exits before rebuilding:

Using Python 3.13.13
Python 3.13.13 already installed at /usr/local/python3.13/bin/python3.13

The Debian 13 side-install wrapper prints the same no-op shape with the interpreter path under /usr/local/python3.13-upstream.

Force a rebuild of the same version only when you changed build dependencies, configure flags, or the installation prefix:

PY313_FORCE_REBUILD=1 update-python313-source

For the Debian 13 upstream side install, force the rebuild through the side-install wrapper:

PY313_FORCE_REBUILD=1 update-python313-upstream

Recreate any venvs that need the rebuilt interpreter after major build-option changes. Existing venvs often keep working across compatible point releases, but rebuilding the venv is cleaner when extension support changed.

Troubleshoot Python 3.13 on Debian

APT Cannot Locate python3.13 on Debian 12 or 11

If sudo apt install python3.13 reports E: Unable to locate package python3.13 on Debian 12 or Debian 11, that is expected with default stable sources. Check for an exact package-name match before changing sources:

apt-cache search --names-only '^python3\.13$'

No matching row means the release does not provide the versioned package. Use the Python.org source build path instead of mixing testing, unstable, or Ubuntu PPAs into a stable Debian system.

Source Helper Refuses to Shadow python3.13

The source helper stops if python3.13 already resolves to another path, such as Debian 13’s /usr/bin/python3.13. Check the active command before rerunning the helper:

command -v python3.13
readlink -f "$(command -v python3.13)"

On Debian 13, keep the APT package and use the python3.13-upstream side-install command when you need the latest upstream point release. On Debian 12 or 11, remove only an old source-built symlink if it points into the same article-owned prefix and you intend to rebuild it:

if [ -L /usr/local/bin/python3.13 ] && [ "$(readlink -f /usr/local/bin/python3.13 2>/dev/null || true)" = /usr/local/python3.13/bin/python3.13 ]; then
    sudo rm -f /usr/local/bin/python3.13
fi

If Debian 13 already has the packaged command, rerun the source build with a separate command name instead of removing the Debian package-owned interpreter:

INSTALL_PREFIX=/usr/local/python3.13-upstream \
PY313_COMMAND_NAME=python3.13-upstream \
./install-python313-source-debian.sh

pip Is Missing Outside a Virtual Environment

Debian’s versioned interpreter package does not mean global pip is ready for that interpreter. On Debian 13 APT installs, if python3.13 -m pip --version fails outside a venv, install the venv package and create a project environment:

sudo apt install python3.13-venv
mkdir -p "$HOME/venvs"
python3.13 -m venv "$HOME/venvs/py313"
source "$HOME/venvs/py313/bin/activate"
python -m pip --version

Skip the APT install line on Debian 12 or Debian 11 when you installed Python 3.13 from source; the source-built interpreter already includes pip support through --with-ensurepip=install. For a Debian 13 upstream side install, use python3.13-upstream -m venv and activate $HOME/venvs/py313-upstream/bin/activate instead.

Missing Modules After a Source Build

Missing modules usually mean the matching -dev package was absent when ./configure ran. Test the modules that most often reveal incomplete build dependencies:

python3.13 -c "import ssl, sqlite3, bz2, lzma, zlib, ctypes, readline, tkinter, dbm.gnu, dbm.sqlite3"

Install the missing development headers, then rebuild. For example, SSL, SQLite, bz2, lzma, and Tkinter support come from these packages:

sudo apt install libssl-dev libsqlite3-dev libbz2-dev liblzma-dev tk-dev
PY313_FORCE_REBUILD=1 update-python313-source

Use PY313_FORCE_REBUILD=1 update-python313-upstream instead when the missing module belongs to the Debian 13 side install. Retest the same import command after the rebuild finishes.

Debian Tools Break After Changing /usr/bin/python3

If APT hooks, desktop update tools, or Python-based Debian utilities fail after manual Python changes, check whether /usr/bin/python3 was replaced or retargeted:

ls -l /usr/bin/python3
dpkg -S /usr/bin/python3

The symlink should remain package-owned by Debian. Reinstall the default Python packages if the symlink or package files were damaged:

sudo apt install --reinstall python3 python3-minimal python3-apt
python3 --version
python3.13 --version 2>/dev/null || true

The first version check verifies Debian’s default interpreter. The second check verifies the separate Python 3.13 command when that branch is installed.

Remove Python 3.13 from Debian

Remove Python 3.13 Development Packages on Debian 13

On Debian 13, keep the default interpreter package in place and remove only the optional venv or development packages when you no longer need them:

sudo apt remove python3.13-venv python3.13-dev

Verify the default interpreter remains available:

python3 --version
python3.13 --version

Do not remove python3, python3-minimal, or the default Debian 13 python3.13 package as routine cleanup.

Remove a Source-Built Python 3.13 Install

Remove the source-built interpreter only when no project or venv still depends on it. Debian’s system Python stays installed.

The cleanup commands permanently delete the source-built Python 3.13 prefixes, build workspace, update helpers, and article-created venvs. The build workspace can contain root-owned files after sudo make altinstall. Back up projects, requirements files, or custom modules before deleting a prefix or venv.

Review the paths that will be removed:

ls -ld /usr/local/python3.13 /usr/local/python3.13-upstream "$HOME/python3.13-source-build" "$HOME/venvs/py313" "$HOME/venvs/py313-upstream" 2>/dev/null || true
command -v python3.13 || true
command -v python3.13-upstream || true
command -v update-python313-source || true
command -v update-python313-upstream || true

Remove the source-built files and refresh the linker cache:

remove_python313_command() {
	link="$1"
	target="$2"
	if [ -L "$link" ]; then
		current_target="$(readlink -f "$link" 2>/dev/null || true)"
		if [ "$current_target" = "$target" ]; then
			sudo rm -f "$link"
		else
			printf 'Leaving non-matching symlink in place: %s\n' "$link" >&2
		fi
	elif [ -e "$link" ]; then
		if [ -f "$link" ] && grep -Fqx '# LinuxCapable Python 3.13 source wrapper' "$link" && grep -Fqx "PY313_SOURCE_TARGET='$target'" "$link"; then
			sudo rm -f "$link"
		else
			printf 'Leaving unmanaged path in place: %s\n' "$link" >&2
		fi
	fi
}

remove_python313_command /usr/local/bin/python3.13 /usr/local/python3.13/bin/python3.13
remove_python313_command /usr/local/bin/python3.13-upstream /usr/local/python3.13-upstream/bin/python3.13
if [ -f /usr/local/bin/update-python313-source ] && grep -Eq 'LinuxCapable Python 3\.13 source helper|PY313_COMMAND_NAME' /usr/local/bin/update-python313-source; then
	sudo rm -f /usr/local/bin/update-python313-source
fi
if [ -f /usr/local/bin/update-python313-upstream ] && grep -Eq 'LinuxCapable Python 3\.13 upstream update wrapper|python3\.13-upstream' /usr/local/bin/update-python313-upstream; then
	sudo rm -f /usr/local/bin/update-python313-upstream
fi
sudo rm -rf /usr/local/python3.13 /usr/local/python3.13-upstream
sudo rm -f /etc/ld.so.conf.d/python3.13.conf /etc/ld.so.conf.d/python3.13-upstream.conf
sudo rm -rf -- "$HOME/python3.13-source-build"
sudo ldconfig
hash -r

Remove only venvs that belong to this interpreter and are no longer needed:

rm -rf "$HOME/venvs/py313" "$HOME/venvs/py313-upstream"

Verify the source-built command is gone while Debian’s default Python remains available:

command -v python3.13-upstream || echo "python3.13-upstream removed from PATH"
if [ ! -x /usr/bin/python3.13 ]; then
    command -v python3.13 || echo "source-built python3.13 removed from PATH"
fi
python3 --version

Python 3.13 References for Debian

Use these official resources when checking release status, package availability, source files, and Python 3.13 behavior:

Conclusion

Python 3.13 is available on Debian with the right ownership model for each release: APT-managed packages on Debian 13, a checksum-verified Python.org source build on Debian 12 and 11, or a separate python3.13-upstream side install on Debian 13 when the newest upstream point release matters. Keep project dependencies in venvs, leave Debian’s default python3 untouched, and rebuild source installs through the matching update helper when new 3.13.x releases arrive.

Share this guide

Help another Linux user troubleshoot faster

Share this guide with someone troubleshooting Linux systems or saving it for later.

Follow LinuxCapable

Want more LinuxCapable guides in Google?

Add LinuxCapable as a preferred source so Google can show more of our fresh Linux tutorials in Top Stories and From your sources when relevant.

Add LinuxCapable as a preferred source on Google
Search LinuxCapable

Need another guide?

Search LinuxCapable for package installs, commands, troubleshooting, and follow-up guides related to what you just read.

Found this guide useful?

Support LinuxCapable to keep tutorials free and up to date.

Buy me a coffeeBuy me a coffee
Before commenting, please review our Comments Policy.
Formatting tips for your comment

You can use basic HTML to format your comment. Useful tags currently allowed in published comments:

You type Result
<code>command</code> command
<strong>bold</strong> bold
<em>italic</em> italic
<blockquote>quote</blockquote> quote block

Got a Question or Feedback?

We read and reply to every comment - let us know how we can help or improve this guide.

Verify before posting: