Closed daisylb closed 4 years ago
Yeah, supplying a full path every time is a bit annoying but how about a less generic key, say, something like "vf new --pyenv 3.7.1 foo"?
For others who were searching for a solution and found this issue: I made a cheap workaround by creating my own 'mkvenv' function. It's very simple and uses the currently active pyenv version to create a new virtualenv using python venv. Sharing it here because it might be useful for others until this issue is resolved:
function mkvenv --description 'Create new Python virtual env in ~/.venv. Uses python venv and current pyenv version (if installed).'
if test (count $argv) -eq 1
# Check which Python version to use
# Using 'python3' to make sure this never uses Mac OS system Python 2
if type -q pyenv
set PYTHON_VERSION (pyenv which python3)
else
set PYTHON_VERSION (which python3)
end
# Set folder to store new venv
set VENV_HOME "$HOME/.venvs/$argv"
# Make sure virtual env doesn't already exist before creating new one
if test -d $VENV_HOME
echo "Virtual env with that name already exists."
else
echo "Creating venv in: $VENV_HOME"
echo "Using Python executable: $PYTHON_VERSION"
command $PYTHON_VERSION -m venv "$VENV_HOME"
echo "Upgrading pip and setuptools to latest versions..."
"$VENV_HOME/bin/pip" install --upgrade pip setuptools
end
else
# Print help message if no, or more than one argv were provided
echo "Usage: mkvenv <name of venv>"
end
end
As a side note: now that Python 2 is officially unsupported, I think it would be nice if virtualfish could use python venv and drop the virtualenv dependency?
@cecep2 said:
now that Python 2 is officially unsupported, I think it would be nice if virtualfish could use python venv and drop the virtualenv dependency?
I agree. See #158.
I put a lot of thought into this, and then I implemented a preliminary solution based on the following analysis…
--pyenv
, --pythonz
, etc.Regarding the less-generic vf new --pyenv 3.7.1 foo
idea, my main problems with that are:
We’d have to implement option flag handlers for each of the tools that provide alternate Python interpreters. That list could include Pyenv, asdf
, Pythonz, Homebrew keg-only versioned Python formulae… At some point the option flag list gets unwieldy.
Some of those option flags (e.g., --pyenv
and --pythonz
) are going to “compete” with --python
for completions, resulting in extra typing to disambiguate.
Most users are only going to use one of the aforementioned alternative Python interpreter installer tools, so folks will be typing things like --pythonz 3.7.1
every time, even though there’s no need for them to disambiguate from, say, Pyenv, which they are very unlikely to also have installed.
-v / --version
The concern with the original -v / --version
idea was that it would break the status quo where vf new
arguments work more-or-less the same as virtualenv
arguments. I’ve already proposed that we switch from Virtualenv to Python’s built-in venv
module, which if adopted would mean that status quo is going to break anyway. But I think the original thought process is sound: it would be nice if vf new
arguments could work more-or-less the same as python -m venv
arguments.
The good news is that arguably the most useful option flags are already consistent between the two virtual environment creation tools:
--clear
--system-site-packages
--symlinks
--copies
--without-pip
--prompt
The most important CLI invocation “signature” difference between the tools is that venv
forgoes Virtualenv’s -p / --python
option flag in favor of building virtual environments with whichever Python interpreter invoked venv
to begin with. I think the best way to handle this is to continue using the vf new -p / --python
convention even if we switch to the venv
module.
I think my main concern with -v / --version
is that the distinction is… muddy. If I want to specify a Homebrew keg-only versioned Python interpreter, do I use -p
or -v
, and why? Ultimately, all of these are simply Python interpreters, so what puts some of them in the -p
camp and others in the -v
camp? Whether they’re on the user’s PATH
or not? I dunno… The more I thought about it, the less clear it all seemed to me.
So for my proof-of-concept implementation, I decided to test how it might work if we used -p / --python
to select any and all interpreters, checking the parsed argument in the following order of priority:
/usr/bin/python3
or a bare Python executable on PATH
(such as pypy
), use it.python3.8
, check for found interpreters in the following order of priority:
/usr/local/opt/python@3.8/bin/python3.8
asdf
Python plugin is installed and has built the specified Python version.As a bonus, for the latter class of cases, I also accepted -p 3.8
and -p 3.9.0a4
. Why make users type -p python3.9.0a4
when it’s clear what they want to do?
I tried to think of use cases that would be confounded by such an implementation, but so far I haven’t come up with any. That said, I imagine such cases must exist, which is why I took the time to write up this detailed explanation, so other people can ponder on it and point out potential problems. (Had to end on a high-alliteration note.) ✨
I have pushed a PR that implements the above hybrid approach, among other features, while sticking with Virtualenv due to its much faster speed: https://github.com/justinmayer/virtualfish/pull/159
Above PR has been merged into master, so this feature has been implemented as outlined above.
So, instead of
vf new -p (pyenv root)/versions/3.5.1/bin/python foo
, users could do e.g.vf new -v 3.5.1 foo
. We'd then detect if pyenv/pythonz is installed and if the appropriate version is present, convert this to the appropriate-p
arg, and invoke virtualenv appropriately.Obviously this would depend on #71. I'm 50/50 on whether I want to break the current status quo where
vf new
arguments work more or less the same asvirtualenv
arguments, though, and I'd love to hear opinions on the matter. (We already sort of violate this withVIRTUALFISH_DEFAULT_PYTHON
, but this is a step further.)