Python
Python is a high-level, interpreted general-purpose programming language, Created by Guido van Rossum in 1991.
In Python, white-space has significance in scope.
Python2 (eol 2020) and Python3 (from 2008) have an incompatible syntax. By default the python interpreter is called with /usr/bin/python3, but a symlink can make python be called without the need to specify a version.
sudo apt install python-is-python3
/usr/bin/python is a symlink to /usr/bin/python3 which in turn is a symlink to /usr/bin/python3.13
python -VV Python 3.13.12 (main, Feb 4 2026, 15:06:39) [GCC 15.2.0]
PIP
PIP is the Python installation manager (and so is PIPX and UV)
https://pip.pypa.io/en/stable/user_guide/
pip config list -v
pip has an optional configuration file
/etc/pip.conf [global] target = /usr/lib/python3/dist-packages
Python packages can be installed with the distribution
apt install python3-numpi apk add py3-numpi
This will pull the package from PYPI and install the package in the dist-pacakges. It's also possible to install your own packages in the site-packages
/usr/lib/python3/dist-packages/ ~/.local/lib/python3.13/site-packages/
To override version numbers and avoid dependency hell, A virtual environment can separate the versions in use, I never use virtual environments, I manage the dependencies instead
python3 -m venv myenv source myenv/bin/activate
PIP can be installed as a distribution package or via a get-pip script
apt install python3-pip wget https://bootstrap.pypa.io/get-pip.py
PIP can run as python module with
python -m pip pip list -v
To prevent apt and pip to install incompatible versions, an externally-managed file prevents packages from being installed with pip unless --break-system-packages is given or the check is removed
sudo rm -f /usr/lib/python3.13/EXTERNALLY-MANAGED
The -v will show where the dependencies are installed and from which package manager they come from, personally I prefer the packages to be installed by pip, but some will come automatically with debian. They can be replaced by removing the package without removing the packages that depend on them and reinstalling them with pip
sudo dpkg --remove --force-depends python3-pygobject
To upgrade all pip packages
pip --disable-pip-version-check list --outdated --format=json | python -c "import json, sys; print('\n'.join([x['name'] for x in json.load(sys.stdin)]))" | xargs -n1 pip install -U
pythonists frown upon version upgrades, because some feel versions should be sticky and new software may introduce depenency incompatibilities (fear of change)
the setup.py contains minimum and maximum versions a module can require.
Advanced stuff
PYCACHE
Wheel
Compile to elf
Certbot
certbot --version
certbot plugins
sudo certbot certonly --dns-azure-config /etc/letsencrypt/azure.cfg -d build.domainname.com
certbot renew --dry-run
Certbot needs a plugin to do DNS validation against Azure DNS. Due to dependency updates, the version range that the plugin requires, the plugin is pegged to an old version of certbot. The original author is not updating these dependencies, nor is merging pull requests, not is answering issues in github.
https://github.com/terricain/certbot-dns-azure
The forks revolve around updating setup.py and snap-requirements.txt, changing between setting and removing upper limits, to avoid upwards incompatibilities.
This worked for me February 2026 for certbot 5.3.1
install_requires = [ 'azure-identity>=1.19.0,<2.0.0', 'azure-mgmt-dns>=8.2.0,<9.0.0', 'azure-core>=1.32.0,<2.0.0', 'setuptools>=41.6.0', 'certbot>=3.0', ]
pip install .
Deepdive
strace -f -e trace=openat,close,read certbot
which python3 /usr/bin/python3 ls -la /usr/bin/python3
ldd /usr/bin/python3.10
linux-vdso.so.1 (0x00007ffd137b7000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7b3f900000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f7b3f8cf000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f7b3f8b3000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7b3f68b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7b3ffe3000)
/usr/bin/python3.10 -V Python 3.10.6
/usr/bin/python3.10 -VV Python 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0]
python3 -c "import sys; print('\n'.join(sys.path))"
/usr/lib/python310.zip /usr/lib/python3.10 /usr/lib/python3.10/lib-dynload /usr/local/lib/python3.10/dist-packages /usr/lib/python3/dist-packages /usr/lib/python3.10/dist-packages
find /usr/lib/python3.10/ -name shutil* /usr/lib/python3.10/shutil.py /usr/lib/python3.10/__pycache__/shutil.cpython-310.pyc
python3-setuptools
PIP
which pip ~/.local/lib/python3.8/site-packages
pip config set global.index-url https://pypi.org/simple python3 -m pip list
python3 -m pip freeze > requirements.txt python3 -m pip install -r requirements.txt --upgrade python -m pip install --upgrade pip pip install numpy
pip install -U `pip list --outdated | awk 'NR>2 {print $1}'`
pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U
pip --disable-pip-version-check list --outdated --format=json | python -c "import json, sys; print('\n'.join([x['name'] for x in json.load(sys.stdin)]))"
pip install --upgrade --upgrade-strategy eager
venv
pyinstaller --onefile --noconfirm --noconsole --clean --log-level=WARN -p . --strip hello.py