pyenv / pyenv

Simple Python version management
MIT License
39.1k stars 3.04k forks source link

pyenv not playing nice with brew "config". [$5] #106

Closed carolyn-idi closed 2 years ago

carolyn-idi commented 10 years ago

I installed python 2.7.6 and python 3.3.3 with pyenv.

Now when I run brew doctor I get the following warning:

Warning: "config" scripts exist outside your system or Homebrew directories.
`./configure` scripts often look for *-config scripts to determine if
software packages are installed, and what additional flags to use when
compiling and linking.

Having additional scripts in your path can confuse software installed via
Homebrew if the config script overrides a system or Homebrew provided
script of the same name. We found the following "config" scripts:

    /Users/insomniac/.pyenv/shims/python-config
    /Users/insomniac/.pyenv/shims/python2-config
    /Users/insomniac/.pyenv/shims/python2.7-config
    /Users/insomniac/.pyenv/shims/python3-config
    /Users/insomniac/.pyenv/shims/python3.3-config
    /Users/insomniac/.pyenv/shims/python3.3m-config

How can this be fixed so it plays nice with brew? C.

--- There is a **[$5 open bounty](https://www.bountysource.com/issues/2813423-pyenv-not-playing-nice-with-brew-config?utm_campaign=plugin&utm_content=tracker%2F282009&utm_medium=issues&utm_source=github)** on this issue. Add to the bounty at [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F282009&utm_medium=issues&utm_source=github).
yyuu commented 10 years ago

Duplication of #42.

This can't be avoidable because pyenv manges shims for these *-config executables if there is CPython installed. I'd like to add some workarounds for this issue if available, but haven't found the way to deal with this yet.

nZac commented 10 years ago

what about just turning off pyenv (comment out the eval and sourcing the rc file) before installing something with brew?

yyuu commented 10 years ago

@nZac You don't have to modify rc file. Just setting the version as system (e.g. pyenv shell system) before installing something with brew can force brew to use system python. Warnings from brew doctor can be safely ignorable in this case.

nZac commented 10 years ago

@yyuu thanks for the details.

Sayhar-zz commented 9 years ago

@yyuu Is setting pyenv shell system recommended for systems with homebrew then?

blueyed commented 9 years ago

@Sayhar If I understand it correctly, it is recommended to use pyenv shell system (for the current shell) before installing something through brew. But it's not recommended in general.

yyuu commented 9 years ago

@blueyed You understand correctly. For the user of pyenv who don't want complicated thing about python installation, I'd recommend to use pyenv shell system when installing something relating to python via brew.

Sayhar-zz commented 9 years ago

This fact sound be displayed much more prominently.

Is there a way to build a config that would take care of this for you? If you think it's possible I'd be happy to help build it On Nov 29, 2014 4:34 AM, "Yamashita, Yuu" notifications@github.com wrote:

@blueyed https://github.com/blueyed You understand correctly. For the user of pyenv who don't want complicated thing about python installation, I'd recommend to use pyenv shell system when installing something relating to python via brew.

— Reply to this email directly or view it on GitHub https://github.com/yyuu/pyenv/issues/106#issuecomment-64946518.

yyuu commented 9 years ago

I don't have any general solution to solve this issue, because this warning is thrown outside from pyenv. Feel free to send patches if someone has idea.

Szkered commented 9 years ago

http://www.task-notes.com/entry/20141223/1419324649 The method used in this post works.

randy3k commented 9 years ago

@Szkered, thanks for the link. I am using the following slightly more generic alias.

alias brew="env PATH=${PATH//$(pyenv root)\/shims:/} brew"
jbpadgett commented 9 years ago

+1 for the alias brew approach above. This fixed the issue for me for now.

wadkar commented 8 years ago

:+1: for @randy3k . Maybe we can add it as a hint in the caveats section when installing with brew?

Too soon; the alias breaks completions. Any ideas how to fix the zsh-completions?

randy3k commented 8 years ago

@wadkar For the same reason...I stopped using it. I now just ignore the warnings...

wadkar commented 8 years ago

Hmm, so if I keep the pyenv global set to system and ignore the brew doctor warnings, I should be good?

wadkar commented 8 years ago

@randy3k Could you please tell me how you're currently handling this issue? Anyone?

akatrevorjay commented 8 years ago

Just use a wrapper script instead of an alias, place it in a prefixed entry in PATH. Completion works great that way. The reason completions don't work is zsh does not complete aliases without the completealias option, and it's off by default for a reason --- it's rather common to break things by design with one.

wadkar commented 8 years ago

TL;DR : Create a script with code in the second block below and name it as brew. Make sure this brew script is executable and is in your ${PATH} before the actual brew which is in /usr/local/bin/brew

Thanks! For the sake of posterity, here's my current solution:

# set path to include personal bin in your .zshrc or .bashrc or whatever
export PATH="${HOME}/bin:${PATH}"

and put following in an executable script in ${HOME}/bin/brew

#!/bin/sh
# check if pyenv is available
# edit: fixed redirect issue in earlier version
if which pyenv > /dev/null 2>&1; then
  # assumes default location of brew in `/usr/local/bin/brew`
  /usr/bin/env PATH="${PATH//$(pyenv root)\/shims:/}" /usr/local/bin/brew "$@"
else
  /usr/local/bin/brew "$@"
fi

Would it be possible to link this issue/comment to wiki/docs?

If you're using tmux then this solution might not work due to duplicate entries in PATH variable. Check my comment below for another solution to fix that problem.

ghost commented 8 years ago

@wadkar do you call this script "brew" or something else?

akatrevorjay commented 8 years ago

Yes, just call it brew. The point is to "wrap" the execution of the original.

wadkar commented 8 years ago

My comment mentions the name of the file as ${HOME}/bin/brew , perhaps it isn't exactly clear. But yeah, what @akatrevorjay said is right on target.

wadkar commented 8 years ago

While using tmux each new shell in tmux will create a login shell. This creates duplicate entries in PATH variable. To avoid duplicate entries, create a ~/.zprofile file and set PATH empty. See this comment for the solution. This question on stackoverflow talks about the problem, and solution.

Here's my current solution for the duplicate entries in $PATH variable. Edit: see comment below by @akatrevorjay on declaring $path as array on ZSH which I think is a better solution (and which I use it personally).

# cat ~/.zprofile
# fix duplicate entries in PATH when using tmux
# see: https://github.com/rbenv/rbenv/issues/369#issuecomment-36010083
if [ -n "${TMUX}" -a -f /etc/profile ]; then
    PATH=''
    source /etc/profile
fi
akatrevorjay commented 8 years ago

Since you're on ZSH, you have the benefit of making an array act as an ordered set:

$path is PATH in array form, -U discards non-unique entries

typeset -U path

Happy hacking!

jcrben commented 7 years ago

If pyenv had a way to use python3 while retaining python as system, that would probably be ideal.

as pointed out in https://github.com/Linuxbrew/legacy-linuxbrew/issues/764#issuecomment-177448686 this is recommended in PEP 0394 as well

soulomoon commented 7 years ago

@wadkar Thank you for the method, now the warning is gone.

should be "2>&1"?

#!/bin/sh
if which pyenv > /dev/null 2>&1; then
  # assumes default location of brew in `/usr/local/bin/brew`
  /usr/bin/env PATH="${PATH//$(pyenv root)\/shims:/}" /usr/local/bin/brew "$@"
else
  /usr/local/bin/brew "$@"
fi
wadkar commented 6 years ago

You are correct. I have edited my response.

urda commented 5 years ago

Fantastic thread, quick note for bash you may see this issue if you use shellcheck:

alias brew="env PATH=${PATH//$(pyenv root)\/shims:/} brew"
                     ^-- SC2139: This expands when defined, not when used. Consider escaping.

Instead I think it's best if you use this instead:

alias brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew'
wadkar commented 5 years ago

Excellent suggestion @urda , I will be using that alias instead of a new binary as I know I will always have pyenv and brew together.

dstroot commented 5 years ago

If you know you are using pyenv shell system when installing something relating to python via brew you can safely just ignore the warnings. This line turns off two checks on my system: stray headers and this one.

brew doctor `brew doctor --list-checks | grep -v -e 'check_for_stray_headers' -e 'check_for_config_scripts'`
kimbaudi commented 5 years ago

@wadkar - you mention earlier that alias breaks zsh-completions, but later you mention that you will be using alias.

does this mean, that alias works fine and does not break zsh-completion? or alias breaks zsh-completion, but you still use it anyways?

kimbaudi commented 5 years ago

so i guess warnings from brew doctor can be safely ignored if you use system version of Python (pyenv shell system) before installing something related to python via brew.

however, this will not suppress the warnings from brew doctor.

if you want to suppress the warnings from brew doctor related to pyenv, alias brew as suggested above: alias brew='env PATH=${PATH//$(pyenv root)\/shims:/} brew'

wadkar commented 5 years ago

@kimbaudi

😂 I find it funny how I forgot why I removed the alias and made it a function call.

Indeed, my zsh still reports brew as a function. So I thought lets change it to the alias and see what happens. Happy to report that the completion works 🎉

I don't know what changed though. If it breaks again, I will change it back to function :)

distractdiverge commented 4 years ago

@Szkered, thanks for the link. I am using the following slightly more generic alias.

alias brew="env PATH=${PATH//$(pyenv root)\/shims:/} brew"

Just add this line to the readme under "Homebrew on macOS"

SmithSamuelM commented 4 years ago

@alexlapinski I can't find the readme you are referencing. Could you be more explicit. I am using macOS catalina with zsh

wadkar commented 4 years ago

@SmithSamuelM I may be wrong, but I think @alexlapinski was referring to the macOS installation/setup instructions.

I was looking to edit the Wiki so that this nugget can be included in it. But I just can't seem to find the edit button. It would be great if a PR or Wiki edit is created so this issue can be put to rest:

TL;DR : won't fix

workaround is to use an alias

alias brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew'

SmithSamuelM commented 4 years ago

Thanks. That helped. My problem was the double quotes @alexlapinski used in his post. His version is broken. Also once I figured that out then @urda gets rid of the interior double quotes.

So I used his version

alias brew='env PATH=${PATH//$(pyenv root)\/shims:/} brew'
wadkar commented 4 years ago

@SmithSamuelM no, you need double quotes inside the single quotes like in my comment:

alias brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew' to be sure you don't mess up your PATH if it contains spaces.

SmithSamuelM commented 4 years ago

@wadkar ok thanks for clarifying

cfont commented 4 years ago

so i guess warnings from brew doctor can be safely ignored if you use system version of Python (pyenv shell system) before installing something related to python via brew.

however, this will not suppress the warnings from brew doctor.

if you want to suppress the warnings from brew doctor related to pyenv, alias brew as suggested above: alias brew='env PATH=${PATH//$(pyenv root)\/shims:/} brew'

for even more clarification, is it recommended to use system version of Python before installing something via brew? in other words, is the current recommendation to use system python and this alias in order to really "fix" everything? or, if we don't want to remember to use system Python when installing something new via brew then should we instead use the executable shell script wrapper identified earlier? or, perhaps setting pyenv shell system is part of the solution, which is fine.

I'm trying to figure this out, learn it from scratch ;-), and make sure I don't skip something important. I've implemented the alias which definitely helped the brew doctor report but now I want to make sure I don't forget this thread and one day in the future install something new via brew and it be messed up and I can't remember why. hope that makes sense and hope you'll bear with me as I figure this out.

wadkar commented 4 years ago

I think when you install something via brew that has python dependencies, then that package will have dependency on brewed python. For example, brew info ansible will show that it Required: libyaml ✔, openssl@1.1 ✔, python@3.8 ✔.

So to answer your question in short, no, I wouldn't link brew installed packages against system python. Therefore, the alias/script removes pyenv from the path before calling brew.

chrisfinazzo commented 3 years ago

Thanks, @wadkar - this alias did the trick for me.

I was a bit concerned about aliasing brew directly, but so far as I can tell, brew config is still accessible and nothing has broken...yet.

slj-butts

Update: Well, shit. Now, when I use thefuck, a program which corrects typos in your Terminal, invoking fuck with no arguments autocompletes what looks like a nonsense line about my $EDITOR variable.

Filed as Issue #1156 with thefuck.

Update #2: Nevermind, carry on, this one was my fault.

sparanoid commented 3 years ago

Here's the fish version:

# Make pyenv play nice with Homebrew
# https://github.com/pyenv/pyenv/issues/106
alias brew="env PATH=(string replace (pyenv root)/shims '' (echo $PATH)) brew"
dfpetrin commented 3 years ago

Correction to the fish version: alias brew="env PATH=(string replace (pyenv root)/shims '' \"\$PATH\") brew"

The previous version expands the current PATH before creating the alias, so if you make any future changes to your path they won't be reflected in the alias. You want the actual alias definition to be: env PATH=(string replace (pyenv root)/shims '' "$PATH") brew

So you need a bunch of escapes for the quote and '$' around the PATH reference in the command defining the alias.

native-api commented 3 years ago

I've added the lines proposed above into the README noting when exactly they are needed. See https://github.com/pyenv/pyenv#homebrew-in-macos

ghost commented 2 years ago

I've added the lines proposed above into the README noting when exactly they are needed. See https://github.com/pyenv/pyenv#homebrew-in-macos

brew outdated does not work when using the "workaround" mentioned:

alias brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew'

native-api commented 2 years ago

@jprokos http://idownvotedbecau.se/itsnotworking/ . Since the alias only removes a PATH entry unrelated to Homebrew, it should not affect Homebrew's metadata searches.

ghost commented 2 years ago

@jprokos http://idownvotedbecau.se/itsnotworking/ .

Since the alias only removes a PATH entry unrelated to Homebrew, it should not affect Homebrew's metadata searches.

Would it matter if the shell was zsh?

I see some earlier comments regarding how zsh interprets aliases.

native-api commented 2 years ago

@jprokos http://idownvotedbecau.se/itsnotworking/ . Since the alias only removes a PATH entry unrelated to Homebrew, it should not affect Homebrew's metadata searches.

Would it matter if the shell was zsh?

I see some earlier comments regarding how zsh interprets aliases.

The command is for Zsh (since it's only applicable for MacOS), I've tested it and it WFM:

% alias                   
brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew'
run-help=man
which-command=whence
% brew outdated
cheat (4.2.2) < 4.2.3
git (2.33.0) < 2.34.1
lua (5.4.3) < 5.4.3_1
pcre2 (10.37_1) < 10.39
pyenv (2.0.7) < 2.2.2
tcl-tk (8.6.11_1) < 8.6.12
dfpetrin commented 2 years ago

Correction to the fish version: alias brew="env PATH=(string replace (pyenv root)/shims '' \"\$PATH\") brew"

The previous version expands the current PATH before creating the alias, so if you make any future changes to your path they won't be reflected in the alias. You want the actual alias definition to be: env PATH=(string replace (pyenv root)/shims '' "$PATH") brew

So you need a bunch of escapes for the quote and '$' around the PATH reference in the command defining the alias.

Ok I have a new update on the fish shell one...

Two versions:

  1. The previous alias–based one with some fixes. 1) env is not required because fish supports setting the variable directly, 2) changed the quoting to get ride of all those ugly escapes, 3) fish tries to be smart about recursion with aliases named the same as the command they're replacing, but generally recommends using command <cmd> instead to be explicit.
    alias brew 'PATH=(string replace (pyenv root)/shims: "" "$PATH") command brew'
  2. The fishy way is to use a function instead of an alias (alias is syntactic sugar for creating a function). So you can just directly save the following as brew.fish under ~/.config/fish/functions (default config location). This function more "correctly" operates on PATH as the array it's actually stored as, instead of getting the string repr and operating on that. It also has the benefit of not failing if for some reason pyenv isn't on the current path.
    function brew
    set -xf PATH $PATH
    if set i (contains -i (pyenv root)/shims $PATH)
        set -e PATH[$i]
    end
    command brew $argv
    end
ghost commented 1 year ago

Is this issue fixed?

Having additional scripts in your path can confuse software installed via Homebrew if the config script overrides a system or Homebrew-provided script of the same name. We found the following "config" scripts: /Users/me/.pyenv/shims/python-config /Users/me/.pyenv/shims/python3-config /Users/me/.pyenv/shims/python3.11-config

Im not sure if this is pyenv problem

Warning: "config" scripts exist outside your system or Homebrew directories. ./configure scripts often look for *-config scripts to determine if software packages are installed, and which additional flags to use when compiling and linking.