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 (1)

Collapse
 
fw7th profile image
7th

Thanks! Saved me like 30 minutes with one websearch.