DEV Community

Cover image for 🐍 Fix Pyenv Messing Up Your Distrobox (Pop!_OS, Ubuntu, Fedora, etc.)
Behzad Seyfi
Behzad Seyfi

Posted on

🐍 Fix Pyenv Messing Up Your Distrobox (Pop!_OS, Ubuntu, Fedora, etc.)

You’ve set up your dream development environment:

  • Your host system (maybe Pop!_OS, Ubuntu, or something similar) uses pyenv to manage many Python versions.
  • For clean, reproducible builds, you spin up a Fedora container with Distrobox.

It feels like the best of both worlds… until something breaks.

Inside your container you type:

~$ which python3
~/.pyenv/shims/python3  😖😩
Enter fullscreen mode Exit fullscreen mode

Instead of Fedora’s Python, it points to your host’s ~/.pyenv/shims/python3.
Your container isn’t clean anymore — your host has leaked into it.

Don’t panic. This is a common issue, and the fix is simple once you know what’s happening.


⚡ The Hidden Culprit: A Pyenv Shell Function

At first, you may think the problem is just the $PATH.
But that’s only part of the story.

The real issue is a pyenv shell function.

When you run this on your host:

eval "$(pyenv init -)"
Enter fullscreen mode Exit fullscreen mode

…it doesn’t only change your path. It also creates a function that overrides python. This function gets copied into your Distrobox container and takes priority over any path fixes you try.

So, to solve this:
👉 You need to remove the shell function and clean the path inside the container.


🛠️ The Smart .bashrc Fix

The best solution is to make your .bashrc “smart.”
With one block of code, it can detect whether you are on the host (Pop!_OS/Ubuntu) or inside a container (Fedora or others).

Replace your current pyenv settings with this block:

# ==================================================================
# Pyenv & Distrobox Isolation
# ==================================================================
# Works on host (Pop!_OS, Ubuntu, etc.) and keeps containers (Fedora, etc.)
# completely clean.

if [ -z "$CONTAINER_ID" ]; then
    # --- HOST SYSTEM ---
    # Normal pyenv setup
    export PYENV_ROOT="$HOME/.pyenv"
    export PATH="$PYENV_ROOT/bin:$PATH"
    eval "$(pyenv init -)"

else
    # --- GUEST (Distrobox Container) ---
    # Aggressively decontaminate the inherited host environment.

    # 1. Disable the pyenv shell function
    pyenv() {
      : # Does nothing
    }

    # 2. Rebuild PATH without pyenv entries
    _CLEAN_PATH=""
    OLD_IFS="$IFS"; IFS=':';
    for p in $PATH; do
        case "$p" in
            # Explicitly skip any path containing .pyenv
            */.pyenv*)
                ;; # Skip pyenv paths
            *)
                if [ -n "$p" ]; then
                    _CLEAN_PATH="${_CLEAN_PATH:+$_CLEAN_PATH:}$p"
                fi
                ;;
        esac
    done
    # Prepend the container's native paths to guarantee priority.
    export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${_CLEAN_PATH}"
    IFS="$OLD_IFS"
    unset _CLEAN_PATH OLD_IFS
fi
Enter fullscreen mode Exit fullscreen mode

After saving, close and reopen your terminals.

  • On your host (Pop!_OS/Ubuntu), pyenv works as usual.
  • Inside your Fedora container, you’ll get a clean, native /usr/bin/python3 🤩😍.

✅ Why This Is the Right Fix

This isn’t a quick hack — it’s a clean, long-term solution.

Pros:

  • One-time setup: Update .bashrc once, and forget about it.
  • True isolation: Both $PATH and the shell function are handled.
  • Future-proof: If you later install pyenv inside the container, it works correctly.
  • Clear boundaries: Keeps host and container separate.

Cons:

  • Works only for bash. If you use zsh or fish, you’ll need to adapt it.
  • Depends on .bashrc being loaded properly.

🎯 Conclusion

With this fix, you get the best of both worlds:

  • Host (Pop!_OS/Ubuntu/ etc.): full pyenv power.
  • Container (Fedora or other Distrobox guests): clean, isolated Python environment.

Now you can code with confidence, without pyenv sneaking into places it doesn’t belong.

Top comments (0)