diff --git a/.config/git/ignore b/.config/git/ignore index ee17658..cbfb1af 100644 --- a/.config/git/ignore +++ b/.config/git/ignore @@ -5,6 +5,14 @@ *.temp *.tmp +# Python +__pycache__/ +*.py[cod] +.python-version +.venv/ +venv/ +.env + # Vim # Source: https://github.com/github/gitignore/blob/main/Global/Vim.gitignore # diff --git a/.config/pypoetry/config.toml b/.config/pypoetry/config.toml new file mode 100644 index 0000000..a815e69 --- /dev/null +++ b/.config/pypoetry/config.toml @@ -0,0 +1,9 @@ +[virtualenvs] + +create = true +in-project = true # .venv/ inside the project, not a central cache + + +[installer] + +parallel = true diff --git a/.config/python/startup.py b/.config/python/startup.py new file mode 100644 index 0000000..b928bbc --- /dev/null +++ b/.config/python/startup.py @@ -0,0 +1,54 @@ +"""Move Python's history file to "$XDG_STATE_HOME/python/history". + +Python 3.13+ honors the `$PYTHON_HISTORY` environment variable, +so this file is only needed for older interpreters (e.g., via `pyenv`). + +`$PYTHONSTARTUP` is executed in the REPL's own namespace +=> Everything is wrapped in a function that is deleted afterwards + to avoid polluting the prompt with temporary names +""" + +import sys + + +def _setup_history(): + if sys.version_info >= (3, 13): + return # `$PYTHON_HISTORY` handles it + + try: + import readline # because it is not in every build + except ImportError: + return + + import atexit + import os + + state_home = os.environ.get("XDG_STATE_HOME") or os.path.join( + os.path.expanduser("~"), ".local", "state" + ) + history_file = os.path.join(state_home, "python", "history") + + os.makedirs(os.path.dirname(history_file), exist_ok=True) + if os.path.isdir(history_file): + raise OSError(history_file + " must not be a directory") + + try: + readline.read_history_file(history_file) + except OSError: # `$PYTHON_HISTORY` is non-existent or unreadable + pass + + readline.set_auto_history(True) + readline.set_history_length(99999) + + def write_history(): + try: + readline.write_history_file(history_file) + except OSError: + pass + + atexit.register(write_history) # Keep a reference to `write_history` + + +_setup_history() + +del _setup_history diff --git a/.config/shell/aliases b/.config/shell/aliases index 522f114..0f47b0e 100644 --- a/.config/shell/aliases +++ b/.config/shell/aliases @@ -112,3 +112,27 @@ if _command_exists git; then alias gsua='git summary --all' fi + + +# Make working with Python more convenient + +alias py='python3' + +ipy() { + if command -v ipython >/dev/null 2>&1; then + ipython "$@" + else + ipython3 "$@" + fi +} + +if _command_exists poetry; then + alias pr='poetry run' +fi + +if _command_exists pyenv; then + alias pyvenvs='pyenv virtualenvs --bare --skip-aliases' + alias pyver='pyenv version' + alias pyvers='pyenv versions --skip-aliases' + alias pywhich='pyenv which' +fi diff --git a/.config/shell/env b/.config/shell/env index cb957f5..76e188f 100644 --- a/.config/shell/env +++ b/.config/shell/env @@ -25,6 +25,7 @@ export DOTFILES_DIR="$XDG_DATA_HOME/dotfiles" # also set in ~/.local/bin/instal export EDITOR=vim export GPG_TTY=$(tty) export PAGER="less --chop-long-lines --ignore-case --LONG-PROMPT --no-init --status-column --quit-if-one-screen" +export PYTHONDONTWRITEBYTECODE=1 export TZ="Europe/Berlin" export VISUAL=$EDITOR @@ -39,4 +40,7 @@ fi export BAT_CONFIG_PATH="$XDG_CONFIG_HOME/bat/config" export LESSHISTFILE="$XDG_STATE_HOME/less/history" export PSQLRC="$XDG_CONFIG_HOME/psql/psqlrc" +export PYENV_ROOT="$XDG_DATA_HOME/pyenv" +export PYTHON_HISTORY="$XDG_STATE_HOME/python/history" +export PYTHONSTARTUP="$XDG_CONFIG_HOME/python/startup.py" export VIMINIT='let $MYVIMRC="'"$XDG_CONFIG_HOME"'/vim/vimrc" | source $MYVIMRC' diff --git a/.local/state/python/.gitkeep b/.local/state/python/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.profile b/.profile index 5a9b03b..3044c61 100644 --- a/.profile +++ b/.profile @@ -60,6 +60,15 @@ fi # Put local executables on the `$PATH` _prepend_to_path "$HOME/.local/bin" +_prepend_to_path "$PYENV_ROOT/bin" + + +if _command_exists pyenv; then + eval "$(pyenv init -)" + if pyenv commands 2>/dev/null | grep -qx 'virtualenv-init'; then + eval "$(pyenv virtualenv-init -)" + fi +fi # When everything is loaded, show a little welcome message