meduz
meduz

Reputation: 4241

How can I make homebrew's python and pyenv live together?

After switching to python 3.4.3 from 2.7.9 (which was quite simple), I often wish to test some of my scripts with python 2.7.9 before sharing them with colleagues. I am using a OSX yosemite platform with everything compiled from homebrew.

The situation was quite ugly (setting PATHes and PYTHONPATH at each step) - until I discovered pyenv which does this very easily and is easily installed using homebrew. So far, so good.

However, now that I am using this version of python, it does not necessarily play well with that of homebrew. Moreover, I found that I could switch back to the system's python, and more generally that pyenv could access that:

$ pyenv versions
  system
  2.7.9
* 3.4.3 (set by /usr/local/var/pyenv/version)

but how could I also add entries for the pythons compiled by homebrew?

Upvotes: 60

Views: 25417

Answers (10)

Gruido
Gruido

Reputation: 71

Pyenv has made a fixed for this and is stated in the man pyenv command. It lets you easily switch between multiple versions of Python. It's simple, unobtrusive, and follows the UNIX tradition of single-purpose tools that do one thing well.

To start using pyenv

  1. Append the following to $HOME/.bashrc
if command -v pyenv 1>/dev/null 2>&1; then
    eval "$(pyenv init -)"
fi

Appending this line enables shims. Please make sure this line is placed toward the end of the shell configuration file since it manipulates PATH during the initialization.

Debian note: Modify only your ~/.bashrc file instead of creating ~/.bash_profile

Zsh note: Modify your ~/.zshrc file instead of ~/.bashrc

Warning: If you configured your system so that BASH_ENV variable points to .bashrc. You should almost certainly put the above mentioned line into .bash_profile, and not into .bashrc. Otherwise you may observe strange behaviour, such as pyenv getting into an infinite loop. See #264 https://github.com/pyenv/pyenv/issues/264 for details.

  1. Restart your shell so the path changes take effect. You can now begin using pyenv.
exec "$SHELL"

Upvotes: 0

TOMARTISAN
TOMARTISAN

Reputation: 1531

2024-12-19 EDIT

Since brew version 4.1.0 (released 2023-07-20) there is a new command called pyenv-sync

So, just run brew pyenv-sync and then you will get enter image description here

If you want to keep pyenv installed as the master version, you can

brew unlink [email protected]
brew unlink [email protected]

To do this can avoid some tools or frameworks which need brew installed python that running well, such as vim

Hope it works!

Upvotes: 0

Frobbit
Frobbit

Reputation: 1712

My updated version of user5354671's function. Optimized to only track dot releases and ignore the symbolic links I was finding with his function

pyenv-brew-relink() {
    rm -f "$HOME/.pyenv/versions/*-brew"
    for i in $(brew --cellar)/python\@* ; do
        #echo i=$i
        for p in $( find $i -depth 1 -type d -print ) ; do
            #echo p=$p
            ln -s -f $p $HOME/.pyenv/versions/${i##/*/}-brew
        done
    done
    pyenv rehash
}


Upvotes: 2

user5354671
user5354671

Reputation: 371

[2022] The python3 versions in homebrew is now in the format of [email protected] so, updated shell

#!/bin/bash

pyenv-brew-relink() {
    rm -f "$HOME/.pyenv/versions/*-brew"
    for i in $(brew --cellar)/python* ; do
      for p in $i/*; do
        echo $p
        ln -s -f $p $HOME/.pyenv/versions/${p##/*/}-brew
      done  
    done
    pyenv rehash
}

pyenv-brew-relink

Upvotes: 10

Dong
Dong

Reputation: 78

pyenv will use system as default version when version is not specified.

When you install python@3 by homebrew and pyenv's version is specified to system, python points to python 2.x in the system and python3 points to python@3 which installed by homebrew.

So usually we don't need to manually add version to pyenv.


In 2020, after `ln -s /outside/python/x.x.x ~/.pyenv/versions/x.x.x`, you need `pyenv rehash` to rehash shims.

Example: add macos system python 2.7 to pyenv

ln -s /System/Library/Frameworks/Python.framework/Versions/2.7 ~/.pyenv/versions/2.7

pyenv rehash

Upvotes: 3

tesch1
tesch1

Reputation: 2806

Pulling all the bits of the previous answers together for one actually working ring to bind them:

pyenv-brew-relink() {
    rm -f "$HOME/.pyenv/versions/*-brew"
    for i in $(brew --cellar)/python* ; do
        ln -s -f "$p" "$HOME/.pyenv/versions/${i##/*/}-brew"
    done
    pyenv rehash
}

Upvotes: 5

decay_of_mind
decay_of_mind

Reputation: 111

A handy function to relink versions:

pyenv-brew-relink() {
  rm -f "$HOME/.pyenv/versions/*-brew"

  for i in $(brew --cellar python)/*; do
    ln -s --force $i $HOME/.pyenv/versions/${i##/*/}-brew;
  done

  for i in $(brew --cellar python@2)/*; do
    ln -s --force $i $HOME/.pyenv/versions/${i##/*/}-brew;
  done
}

Upvotes: 9

xuru
xuru

Reputation: 31

Just to add to @johnizzo1's answer, python2 is now python@2, so you should change the python3 for loop to something like:

for i in `ls $(brew --cellar python)/`; do 
  ln -s $(brew --cellar python)/$i $HOME/.pyenv/versions/$i-brew; 
done

for i in `ls $(brew --cellar python@2)/`; do 
  ln -s $(brew --cellar python@2)/$i $HOME/.pyenv/versions/$i-brew; 
done

Upvotes: 3

mipadi
mipadi

Reputation: 410662

You can install pyenv in your home directory (as described in pyenv's installation guide), and then create a symlink at ~/.pyenv/versions to $(brew --cellar)/python:

ln -s $(brew --cellar python)/* ~/.pyenv/versions/

The way Homebrew works nowadays, this will pick up both 2.x and 3.x.

Upvotes: 71

johnrizzo1
johnrizzo1

Reputation: 31

Well if you want the pyenv pythons and homebrew pythons to live together you need to make the name of the homebrew pythons something other than the version. Otherwise they will clash with the directory names that pyenv uses. For example, if you want to install pyenv python 2.7.11 and homebrew python 2.7.11 you could do something like this.

for i in `ls $(brew --cellar python)/`; do 
  ln -s $(brew --cellar python)/$i $HOME/.pyenv/versions/$i-brew; 
done

for i in `ls $(brew --cellar python3)/`; do 
  ln -s $(brew --cellar python)/$i $HOME/.pyenv/versions/$i-brew; 
done

Essentially this will create a directory in $HOME/.pyenv/versions appended with '-brew' so that it won't clash with the pyenv pythons.

Upvotes: 3

Related Questions