justinmayer/virtualfish

VirtualFish is not accessible after simple pip install

redlickigrzegorz opened this issue Β· 22 comments

  • I am using Fish shell version 3.1 or higher.
  • I am using Python version 3.6 or higher.
  • I have searched the issues (including closed ones) and believe that this is not a duplicate.
  • OS version and name: macOS Catalina version: 10.15.4
  • Fish shell version: 3.1.2
  • VirtualFish version: 2.2.3

Issue

I am using VirtualFish for a while but recently I have changed my computer (given by the company) and I needed to configure my environment once again after a long time not doing that.

I have followed the instruction placed in README.md file and unfortunately, I found a problem with triggering the second command πŸ˜•
The main problem is that vf command can't be recognized as a global command for my machine. I suppose that this problem can be connected somehow with my computer, not with a particular bug in the library but the installation process with the usage of pip package installer didn't inform me about that πŸ€·β€β™€οΈ

I have installed VirtualFish with the usage of directly run cli.py module with the install argument and it works like a charm πŸ™Œ but I am pretty sure that something should be updated: either documentation or code 🧐

Hi Grzegorz. I'm sorry to hear the installation process was not a smooth one for you.

[…] but the installation process with the usage of pip package installer didn't inform me about that πŸ€·β€β™€οΈ

I'm not sure I understand this part. Could you elaborate further?

Yes, of course πŸ™‚
In the documentation, there are several separate steps to start working with VirtualFish, but two first are interesting for me:

  1. pip install virtualfish
  2. vf install
  3. ...

I suppose that if I can't run the second command, the first one should inform me that something goes wrong - that's why I wrote that pip didn't say anything πŸ˜‰
But maybe there is an additional missing step between and pip shouldn't tell anything.

For what it's worth, I cannot replicate the behavior you mentioned:

~ ➀ trash ~/.config/fish/conf.d/virtualfish-loader.fish
~ ➀ exec fish  # Now `vf` command should no longer be recognized
~ ➀ vf
fish: Unknown command: vf
fish:
 vf
 ^
~ ➀ python -m venv ~/Virtualenvs/tempenv
~ ➀ source ~/Virtualenvs/tempenv/bin/activate.fish
(tempenv) ~ ➀ pip install virtualfish
(tempenv) ~ ➀ vf --version
VirtualFish is not installed. Run 'vf install' to install it, then run 'exec fish' to restart your shell and load it.
(tempenv) ~ ➀ vf install
VirtualFish is now installed! Run 'exec fish' to reload Fish, and you'll be able to use it!

In your case, Pip-installing VirtualFish does not result in having the vf command available on $PATH β€” I don't know why. As you said, it could be something particular to your system. What is the path to the Python interpreter you used to Pip-install VirtualFish? What is displayed when you run the following command?

grep VIRTUALFISH_PYTHON_EXEC ~/.config/fish/conf.d/virtualfish-loader.fish

If someone successfully installs a Python package via Pip, but then that package's entry point (in this case, vf) is not subsequently available to the user for some reason, then there isn't really anything we can do to tell the user that something didn't work correctly. We have no way to determine that. While in theory it is possible to use a Setuptools post-installation step to check for that condition, we switched from Setuptools to Poetry, the latter of which intentionally does not support arbitrary Python code execution during package installation (for security reasons).

In short, it would helpful to determine why installing the virtualfish package did not result in vf being available on your $PATH, because that is what should have happened.

That's very interesting what you described above and helpful as well❗

I have done the additional tests on my second computer where I didn't have any problems with VirtualFish before. Probably, I have installed it there when VirtualFish needed to be eval manually in the config.fish file πŸ˜‰
Unfortunately, the result of my tests was exactly the same as on my problematic computer. After the pip install virtualfish command triggered, I couldn't trigger vf to finish installation process - the command wasn't recognized.

There is only one difference between my installation and the one described by you. I haven't used a virtual environment to do this, I have used pip for Python3 installed globally 😬
When I created the temporary venv first, and after that install virtualfish, everything is working correctly, exactly like it is described in the instruction πŸŽ‰

To answer your question virtualfish-loader.fish contained such a line previously:

set -g VIRTUALFISH_PYTHON_EXEC /usr/local/bin/python3

but now, it looks this way:

set -g VIRTUALFISH_PYTHON_EXEC /Users/<username>/.virtualenvs/virtualfish/bin/python3

If it is the proper way of installing VirtualFish, I think it should be described this way in the documentation to avoid future problems. But if you think, it should work with global Python3 as well, I can share more things with you to try to resolve this issue πŸ˜‰

I'm sorry for not being more clear... My example above was just to indicate that VirtualFish seems to be operating correctly β€” not to suggest that VirtualFish should be installed in a virtual environment. On the contrary, for most situations, I think it is better to install VirtualFish outside of a virtual environment. I only installed VirtualFish in a virtual environment in my example above so that the test could be done in an isolated environment without being exposed to the vf executable already on my $PATH.

I suspect this is caused by something in your Python environment. What is your primary, default Python β€” Homebrew, macOS default, something else?

What do you see when you run which python outside of a virtual environment? What about python --version?

Oh, but it helped... 😐

About my Python:

  1. Downloaded from this page and installed with the usage of the installer.
  2. which python3 --> /usr/local/bin/python3 which is a symlink to /Library/Frameworks/Python.framework/Versions/3.7/bin/python3
  3. python3 --version --> Python 3.7.7

That's useful to know, but what I asked about was which python and python --version specifically. Not the python3 commands.

Also, what was the exact command you used to install VirtualFish the first time? (i.e., before doing so inside a virtual environment)

To be honest, I am using python3 because it is the command for Python in version 3. Simple python means Python2 to me which is deprecated and I am using it only for the projects which need to be run in this version πŸ˜‰Sorry for not telling that before πŸ˜•

So, to install VirtualFish outside the virtual environment, I have used pip3 install virtualfish command which means the usage of pip for Python3.
pip3 --version --> pip 19.2.3 from /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pip (python 3.7)

I have tried to process the whole installation with Python2 but without success. However, I can tell more about it because it looks very similar:

  1. Downloaded from this page and installed with the usage of the installer.
  2. which python --> /usr/local/bin/python which is a symlink to /Library/Frameworks/Python.framework/Versions/2.7/bin/python
  3. python --version --> Python 2.7.18

Simple python means Python2 to me which is deprecated

I can understand why you would feel that way, but that is not the official Python plan as outlined in PEP 394. The idea was for python to refer to Python 2, but only until the official retirement of Python 2. Since the latter has already happened, python should now refer to Python 3. In fact, on my Homebrew version of Python, python --version yields Python 3.7.7. For more information, please refer to PEP 394.

Python 2 is not just deprecated β€” it is officially no longer supported… not by the Python Software Foundation, and neither by VirtualFish. 😊 I never intended for you to install Python 2, so I think it would be best to uninstall it from your system.

... which really brings us back to the original question: Assuming you have uninstalled Python 2, what does which python and python --version return?

Yes, probably you are right, however as I said before, I am using Python2 for the projects which need to be run with the usage of this version - I can't just delete it πŸ˜‰
Maybe I could spend additional time setting up my environment in a new/better way where Python2 will be accessible as well and it won't be problematic but unfortunately, I got used to the current way of working.

If python command points exactly the same what my current python3 command, do you think it will change anything? In my opinion, it shouldn't because it is only the name of the command. But maybe you mean that I should install Python with the usage of Homebrew that makes sense to me and it sounds very easy but again, I need to change my habits to start working this way πŸ˜‰

I assume that this line of the code is responsible for adding working vf command. So I will try to find some time (even maybe this week) to debug it and to find the real reason πŸ™‚

Hey, I'm having issues with installing virtualfish as well.

I did pip install --user virtualfish

 $ fish --version
fish, version 3.1.2

$  which python
python is /usr/bin/python

$ python --version
Python 3.6.9

$ which virtualfish
vf is /home/william/.local/bin/vf

$ vf install
The subcommand install is not defined

Never the less...

$ vf 
Usage: vf <command> [<args>]

Available commands:

    activate        # Defined in /home/william/.tackle/modules/virtualfish/virtual.fish @ line 74
    addpath         # Defined in /home/william/.tackle/modules/virtualfish/virtual.fish @ line 219
    all             # Defined in /home/william/.tackle/modules/virtualfish/virtual.fish @ line 256
    cd              # Defined in /home/william/.tackle/modules/virtualfish/virtual.fish @ line 184
    cdpackages      # Defined in /home/william/.tackle/modules/virtualfish/virtual.fish @ line 192
    connect         # Defined in /home/william/.tackle/modules/virtualfish/virtual.fish @ line 286
    deactivate      # Defined in /home/william/.tackle/modules/virtualfish/virtual.fish @ line 111
    environment     # Defined in /home/william/.tackle/modules/virtualfish/environment.fish @ line 75
    help            # Defined in /home/william/.tackle/modules/virtualfish/virtual.fish @ line 294
    ls              # Defined in /home/william/.tackle/modules/virtualfish/virtual.fish @ line 176
    lsprojects      # Defined in /home/william/.tackle/modules/virtualfish/virtualprojects.fish @ line 49
    new             # Defined in /home/william/.tackle/modules/virtualfish/virtual.fish @ line 146
    project         # Defined in /home/william/.tackle/modules/virtualfish/virtualprojects.fish @ line 36
    rm              # Defined in /home/william/.tackle/modules/virtualfish/virtual.fish @ line 163
    tmp             # Defined in /home/william/.tackle/modules/virtualfish/virtual.fish @ line 197
    workon          # Defined in /home/william/.tackle/modules/virtualfish/virtualprojects.fish @ line 9

For full documentation, see: http://virtualfish.readthedocs.org/en/latest/

I don't know if the above is from my previously installed virtualfish.

 $ vf new test_vf
created virtual environment CPython3.6.9.final.0-64 in 156ms
  creator CPython3Posix(dest=/home/william/.virtualenvs/test_vf, clear=False, global=False)
  seeder FromAppData(download=False, pip=latest, setuptools=latest, wheel=latest, via=copy, app_data_dir=/home/william/.local/share/virtualenv/seed-app-data/v1.0.1)
  activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator

 $ which python
python is /home/william/.virtualenvs/test_vf/bin/python

So I guess vf 'works' but now there's a lot of extraneous messages in my output, and my vf plugins are not working.

That didn't work... unfortunately I can no longer create a new virtual environment.

 $ vf new test_virtualfish
VirtualFish requires Fish 3.1 or higher. Current version: 3.1.2
 $ fish --version
fish, version 3.1.2

$ python --version
Python 3.6.9

@whwkong: I recently added that Fish version check because folks were filing issues that were caused by using outdated Fish versions. As you can see in the relevant code, the version comparison should not produce the result you encountered. Here's what happens when I run that code in a Python REPL:

~ ➀ python
Python 3.7.7 (default, Mar 10 2020, 15:43:27)
>>> pip install packaging
>>> import subprocess
>>> from packaging import version
>>> cmd = ["fish", "-c", "echo $version"]
>>> current_fish_version = subprocess.check_output(cmd).decode("utf-8").strip()
>>> print(version.parse(current_fish_version))
3.1.2
>>> minimum_fish_version = "3.1"
>>> print(version.parse(current_fish_version) < version.parse(minimum_fish_version))
False
>>> print(version.parse(current_fish_version) > version.parse(minimum_fish_version))
True

So I am baffled as to why that version comparison test failed in your case. Nonetheless, I suppose I can remove the exit() directive, effectively changing the Fish version check into merely a warning instead of preventing further VirtualFish use.

In the interim, in you should be able to comment out the check_fish_version() call on line 35 in /home/william/.local/lib/python3.7/site-packages/virtualfish/loader/cli.py and then run the following command to install the VirtualFish loader:

python /home/william/.local/lib/python3.7/site-packages/virtualfish/loader/cli.py install environment projects

I would really like to understand why the version check failed in your case, so if you find any information that would have led to that result, by all means please let me know.

@redlickigrzegorz: No need to uninstall Python 2 if you are using it. I misunderstood and thought you had just installed it during our correspondence. To me, the crux of the issue is this: you installed the VirtualFish Python package via pip3 install virtualfish, but that did not result in you having a vf executable on your $PATH. Why not? What happens when you use pip3 to install other CLI tools? Are those tools accessible after installation?

@justinmayer Yes, totally agree with you. It is the crux of the issue but to be honest, I am not sure if I installed anything else than VirtualFish which should be accessible globally that way, so I can't answer this question... When I am working on my projects, I always install things with the usage of virtualenv πŸ˜‰

Can you provide the example of the library which uses poetry and gives executable commands? I can give it a try πŸ˜‰
Now, It looks like a problem strictly connected with poetry.

It looks like a problem strictly connected with Poetry.

I'm not sure how you reached that conclusion. I don't see any evidence that implicates Poetry here. There are many projects that use Poetry to publish packages with exposed entry-points / executables, including Poetry itself. As another example, here is a test run that shows Poetry building an Pelican sdist, including subsequent successful installation via Pip: https://github.com/getpelican/pelican/runs/689140509?check_suite_focus=true#step:4:109

Try installing any other Python-based CLI tool via pip3, and you will almost certainly run into the same problem: it won't be available on your $PATH. I have seen this problem before when there are Python 2 and Python 3 interpreters installed β€” one of them puts installed package executables somewhere on $PATH (e.g., /usr/local/bin/foo), and the other one doesn't.

I am nearly certain that is the source of the problem β€” not Poetry, and not VirtualFish.

[tool.poetry.scripts]
vf = "virtualfish.loader.cli:main"

It looks like something that is set by poetry, that's the cause of my conclusion πŸ˜‰ But it is your library, you know better - I am not even using poetry in my projects.

Anyway, it looks like you are right, I have tested this library and after installing it with the usage of pip3, I am not able to access command, when pip is working... (I know that it is not a perfect proof because my pip points to Python2 but it is still very interesting topic).

I think that it is enough information for me to close this issue, don't you think? πŸ€”

@justinmayer
Thanks for your reply. I had some time to step through the code. The result of the subprocess check on cmd = ["fish", "-c", "echo $version"] was that fish_result had a value of:

>>> fish_result
'\x1b[32mloading local fish...\n\x1b(B\x1b[m3.1.2'

This was due to my echoing a string within a script that was part of my config.fish. I removed it and virtualfish worked fine.

Many thanks for the additional info, @whwkong. I'm not sure whether there's much we could do to catch situations like the one you describe and sanitize the result in a consistent manner. But I'm making a few changes, in part to address #177, that will at least change the behavior to a warning instead of a show-stopping error.

Hi,

I have installed today Virtualfish in my new macos and I can't find vf command.
After reading a lot in the web and into Virtualfish sources, I realized that using this command:
pip3 install virtualfish solves the problem instead of using the official command python -m pip install --user virtualfish.
Maybe can help someone else, also me in the future :)

Hi Valentino. The current documented install command assumes python points to a Python 3.x interpreter. If that is not the case on your system, then the recommended installation command would instead be:

python3 -m pip install --user virtualfish